Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php b/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php
index 86dbad6307..ccc2756557 100644
--- a/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php
+++ b/src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php
@@ -1,72 +1,75 @@
<?php
final class PhabricatorConpherenceThreadPHIDType extends PhabricatorPHIDType {
const TYPECONST = 'CONP';
public function getTypeName() {
return pht('Conpherence Thread');
}
public function newObject() {
return new ConpherenceThread();
}
public function getPHIDTypeApplicationClass() {
return 'PhabricatorConpherenceApplication';
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new ConpherenceThreadQuery())
->needParticipantCache(true)
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$thread = $objects[$phid];
- $data = $thread->getDisplayData($query->getViewer());
- $handle->setName($data['title']);
- $handle->setFullName($data['title']);
- $handle->setURI('/'.$thread->getMonogram());
+
+ $title = $thread->getDisplayTitle($query->getViewer());
+ $monogram = $thread->getMonogram();
+
+ $handle->setName($title);
+ $handle->setFullName(pht('%s: %s', $monogram, $title));
+ $handle->setURI('/'.$monogram);
}
}
public function canLoadNamedObject($name) {
return preg_match('/^Z\d*[1-9]\d*$/i', $name);
}
public function loadNamedObjects(
PhabricatorObjectQuery $query,
array $names) {
$id_map = array();
foreach ($names as $name) {
$id = (int)substr($name, 1);
$id_map[$id][] = $name;
}
$objects = id(new ConpherenceThreadQuery())
->setViewer($query->getViewer())
->withIDs(array_keys($id_map))
->execute();
$objects = mpull($objects, null, 'getID');
$results = array();
foreach ($objects as $id => $object) {
foreach (idx($id_map, $id, array()) as $name) {
$results[$name] = $object;
}
}
return $results;
}
}
diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php
index a705c450bf..03f8f6997e 100644
--- a/src/applications/conpherence/storage/ConpherenceThread.php
+++ b/src/applications/conpherence/storage/ConpherenceThread.php
@@ -1,473 +1,484 @@
<?php
final class ConpherenceThread extends ConpherenceDAO
implements
PhabricatorPolicyInterface,
PhabricatorApplicationTransactionInterface,
PhabricatorMentionableInterface,
PhabricatorDestructibleInterface {
protected $title;
protected $imagePHIDs = array();
protected $isRoom = 0;
protected $messageCount;
protected $recentParticipantPHIDs = array();
protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
protected $joinPolicy;
private $participants = self::ATTACHABLE;
private $transactions = self::ATTACHABLE;
private $handles = self::ATTACHABLE;
private $filePHIDs = self::ATTACHABLE;
private $widgetData = self::ATTACHABLE;
private $images = self::ATTACHABLE;
public static function initializeNewThread(PhabricatorUser $sender) {
return id(new ConpherenceThread())
->setMessageCount(0)
->setTitle('')
->attachParticipants(array())
->attachFilePHIDs(array())
->attachImages(array())
->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy(PhabricatorPolicies::POLICY_USER)
->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
}
public static function initializeNewRoom(PhabricatorUser $creator) {
return id(new ConpherenceThread())
->setIsRoom(1)
->setMessageCount(0)
->setTitle('')
->attachParticipants(array())
->attachFilePHIDs(array())
->attachImages(array())
->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy($creator->getPHID())
->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'recentParticipantPHIDs' => self::SERIALIZATION_JSON,
'imagePHIDs' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'title' => 'text255?',
'isRoom' => 'bool',
'messageCount' => 'uint64',
'mailKey' => 'text20',
'joinPolicy' => 'policy',
),
self::CONFIG_KEY_SCHEMA => array(
'key_room' => array(
'columns' => array('isRoom', 'dateModified'),
),
'key_phid' => null,
'phid' => array(
'columns' => array('phid'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorConpherenceThreadPHIDType::TYPECONST);
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));
}
return parent::save();
}
public function getMonogram() {
return 'Z'.$this->getID();
}
public function getImagePHID($size) {
$image_phids = $this->getImagePHIDs();
return idx($image_phids, $size);
}
public function setImagePHID($phid, $size) {
$image_phids = $this->getImagePHIDs();
$image_phids[$size] = $phid;
return $this->setImagePHIDs($image_phids);
}
public function getImage($size) {
$images = $this->getImages();
return idx($images, $size);
}
public function setImage(PhabricatorFile $file, $size) {
$files = $this->getImages();
$files[$size] = $file;
return $this->attachImages($files);
}
public function attachImages(array $files) {
assert_instances_of($files, 'PhabricatorFile');
$this->images = $files;
return $this;
}
private function getImages() {
return $this->assertAttached($this->images);
}
public function attachParticipants(array $participants) {
assert_instances_of($participants, 'ConpherenceParticipant');
$this->participants = $participants;
return $this;
}
public function getParticipants() {
return $this->assertAttached($this->participants);
}
public function getParticipant($phid) {
$participants = $this->getParticipants();
return $participants[$phid];
}
public function getParticipantIfExists($phid, $default = null) {
$participants = $this->getParticipants();
return idx($participants, $phid, $default);
}
public function getParticipantPHIDs() {
$participants = $this->getParticipants();
return array_keys($participants);
}
public function attachHandles(array $handles) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$this->handles = $handles;
return $this;
}
public function getHandles() {
return $this->assertAttached($this->handles);
}
public function attachTransactions(array $transactions) {
assert_instances_of($transactions, 'ConpherenceTransaction');
$this->transactions = $transactions;
return $this;
}
public function getTransactions($assert_attached = true) {
return $this->assertAttached($this->transactions);
}
public function hasAttachedTransactions() {
return $this->transactions !== self::ATTACHABLE;
}
public function getTransactionsFrom($begin = 0, $amount = null) {
$length = count($this->transactions);
return array_slice(
$this->getTransactions(),
$length - $begin - $amount,
$amount);
}
public function attachFilePHIDs(array $file_phids) {
$this->filePHIDs = $file_phids;
return $this;
}
public function getFilePHIDs() {
return $this->assertAttached($this->filePHIDs);
}
public function attachWidgetData(array $widget_data) {
$this->widgetData = $widget_data;
return $this;
}
public function getWidgetData() {
return $this->assertAttached($this->widgetData);
}
public function loadImageURI($size) {
$file = $this->getImage($size);
if ($file) {
return $file->getBestURI();
}
return PhabricatorUser::getDefaultProfileImageURI();
}
- public function getDisplayData(PhabricatorUser $user) {
+
+ /**
+ * Get the thread's display title for a user.
+ *
+ * If a thread doesn't have a title set, this will return a string describing
+ * recent participants.
+ *
+ * @param PhabricatorUser Viewer.
+ * @return string Thread title.
+ */
+ public function getDisplayTitle(PhabricatorUser $viewer) {
+ $title = $this->getTitle();
+ if (strlen($title)) {
+ return $title;
+ }
+
+ return $this->getRecentParticipantsString($viewer);
+ }
+
+
+ /**
+ * Get recent participants (other than the viewer) as a string.
+ *
+ * For example, this method might return "alincoln, htaft, gwashington...".
+ *
+ * @param PhabricatorUser Viewer.
+ * @return string Description of other participants.
+ */
+ private function getRecentParticipantsString(PhabricatorUser $viewer) {
+ $handles = $this->getHandles();
+ $phids = $this->getOtherRecentParticipantPHIDs($viewer);
+
+ $limit = 3;
+ $more = (count($phids) > $limit);
+ $phids = array_slice($phids, 0, $limit);
+
+ $names = array_select_keys($handles, $phids);
+ $names = mpull($names, 'getName');
+ $names = implode(', ', $names);
+
+ if ($more) {
+ $names = $names.'...';
+ }
+
+ return $names;
+ }
+
+
+ /**
+ * Get PHIDs for recent participants who are not the viewer.
+ *
+ * @param PhabricatorUser Viewer.
+ * @return list<phid> Participants who are not the viewer.
+ */
+ private function getOtherRecentParticipantPHIDs(PhabricatorUser $viewer) {
+ $phids = $this->getRecentParticipantPHIDs();
+ $phids = array_fuse($phids);
+ unset($phids[$viewer->getPHID()]);
+ return array_values($phids);
+ }
+
+
+ public function getDisplayData(PhabricatorUser $viewer) {
+ $handles = $this->getHandles();
+
if ($this->hasAttachedTransactions()) {
$transactions = $this->getTransactions();
} else {
$transactions = array();
}
- $set_title = $this->getTitle();
-
- if ($set_title) {
- $title_mode = 'title';
- } else {
- $title_mode = 'recent';
- }
if ($transactions) {
$subtitle_mode = 'message';
} else {
$subtitle_mode = 'recent';
}
- $recent_phids = $this->getRecentParticipantPHIDs();
- $handles = $this->getHandles();
- // Luck has little to do with it really; most recent participant who
- // isn't the user....
- $lucky_phid = null;
- $lucky_index = null;
- $recent_title = null;
- foreach ($recent_phids as $index => $phid) {
- if ($phid == $user->getPHID()) {
- continue;
- }
- $lucky_phid = $phid;
- break;
- }
- reset($recent_phids);
-
+ $lucky_phid = head($this->getOtherRecentParticipantPHIDs($viewer));
if ($lucky_phid) {
$lucky_handle = $handles[$lucky_phid];
} else {
// This will be just the user talking to themselves. Weirdo.
$lucky_handle = reset($handles);
}
$img_src = null;
$size = ConpherenceImageData::SIZE_CROP;
if ($this->getImagePHID($size)) {
$img_src = $this->getImage($size)->getBestURI();
} else if ($lucky_handle) {
$img_src = $lucky_handle->getImageURI();
}
- if ($title_mode == 'recent' || $subtitle_mode == 'recent') {
- $count = 0;
- $final = false;
- foreach ($recent_phids as $phid) {
- if ($phid == $user->getPHID()) {
- continue;
- }
- $handle = $handles[$phid];
- if ($recent_title) {
- if ($final) {
- $recent_title .= '...';
- break;
- } else {
- $recent_title .= ', ';
- }
- }
- $recent_title .= $handle->getName();
- $count++;
- $final = $count == 3;
- }
- }
-
- switch ($title_mode) {
- case 'recent':
- $title = $recent_title;
- $js_title = $recent_title;
- break;
- case 'title':
- $title = $js_title = $this->getTitle();
- break;
- }
-
$message_title = null;
if ($subtitle_mode == 'message') {
$message_transaction = null;
foreach ($transactions as $transaction) {
switch ($transaction->getTransactionType()) {
case PhabricatorTransactions::TYPE_COMMENT:
$message_transaction = $transaction;
break 2;
default:
break;
}
}
if ($message_transaction) {
$message_handle = $handles[$message_transaction->getAuthorPHID()];
$message_title = sprintf(
'%s: %s',
$message_handle->getName(),
id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs(60)
->truncateString(
$message_transaction->getComment()->getContent()));
}
}
switch ($subtitle_mode) {
case 'recent':
- $subtitle = $recent_title;
+ $subtitle = $this->getRecentParticipantsString($viewer);
break;
case 'message':
if ($message_title) {
$subtitle = $message_title;
} else {
- $subtitle = $recent_title;
+ $subtitle = $this->getRecentParticipantsString($viewer);
}
break;
}
- $user_participation = $this->getParticipantIfExists($user->getPHID());
+ $user_participation = $this->getParticipantIfExists($viewer->getPHID());
if ($user_participation) {
$user_seen_count = $user_participation->getSeenMessageCount();
} else {
$user_seen_count = 0;
}
$unread_count = $this->getMessageCount() - $user_seen_count;
+ $title = $this->getDisplayTitle($viewer);
+
return array(
'title' => $title,
- 'js_title' => $js_title,
'subtitle' => $subtitle,
'unread_count' => $unread_count,
'epoch' => $this->getDateModified(),
'image' => $img_src,
);
}
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
PhabricatorPolicyCapability::CAN_JOIN,
);
}
public function getPolicy($capability) {
if ($this->getIsRoom()) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
case PhabricatorPolicyCapability::CAN_JOIN:
return $this->getJoinPolicy();
}
}
return PhabricatorPolicies::POLICY_NOONE;
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
// this bad boy isn't even created yet so go nuts $user
if (!$this->getID()) {
return true;
}
if ($this->getIsRoom()) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_EDIT:
case PhabricatorPolicyCapability::CAN_JOIN:
return false;
}
}
$participants = $this->getParticipants();
return isset($participants[$user->getPHID()]);
}
public function describeAutomaticCapability($capability) {
if ($this->getIsRoom()) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return pht('Participants in a room can always view it.');
break;
}
} else {
return pht('Participants in a thread can always view and edit it.');
}
}
public static function loadPolicyObjects(
PhabricatorUser $viewer,
array $conpherences) {
assert_instances_of($conpherences, 'ConpherenceThread');
$grouped = mgroup($conpherences, 'getIsRoom');
$rooms = idx($grouped, 1, array());
$policies = array();
foreach ($rooms as $room) {
$policies[] = $room->getViewPolicy();
}
$policy_objects = array();
if ($policies) {
$policy_objects = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->withPHIDs($policies)
->execute();
}
return $policy_objects;
}
public function getPolicyIconName(array $policy_objects) {
assert_instances_of($policy_objects, 'PhabricatorPolicy');
if ($this->getIsRoom()) {
$icon = $policy_objects[$this->getViewPolicy()]->getIcon();
} else if (count($this->getRecentParticipantPHIDs()) > 2) {
$icon = 'fa-users';
} else {
$icon = 'fa-user';
}
return $icon;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new ConpherenceEditor();
}
public function getApplicationTransactionObject() {
return $this;
}
public function getApplicationTransactionTemplate() {
return new ConpherenceTransaction();
}
public function willRenderTimeline(
PhabricatorApplicationTransactionView $timeline,
AphrontRequest $request) {
return $timeline;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$participants = id(new ConpherenceParticipant())
->loadAllWhere('conpherencePHID = %s', $this->getPHID());
foreach ($participants as $participant) {
$participant->delete();
}
$this->saveTransaction();
}
}
diff --git a/src/applications/conpherence/view/ConpherenceDurableColumnView.php b/src/applications/conpherence/view/ConpherenceDurableColumnView.php
index d9462b1281..f52f48c8e6 100644
--- a/src/applications/conpherence/view/ConpherenceDurableColumnView.php
+++ b/src/applications/conpherence/view/ConpherenceDurableColumnView.php
@@ -1,541 +1,541 @@
<?php
final class ConpherenceDurableColumnView extends AphrontTagView {
private $conpherences = array();
private $draft;
private $selectedConpherence;
private $transactions;
private $visible;
private $initialLoad = false;
private $policyObjects;
private $quicksandConfig = array();
public function setConpherences(array $conpherences) {
assert_instances_of($conpherences, 'ConpherenceThread');
$this->conpherences = $conpherences;
return $this;
}
public function getConpherences() {
return $this->conpherences;
}
public function setDraft(PhabricatorDraft $draft) {
$this->draft = $draft;
return $this;
}
public function getDraft() {
return $this->draft;
}
public function setSelectedConpherence(
ConpherenceThread $conpherence = null) {
$this->selectedConpherence = $conpherence;
return $this;
}
public function getSelectedConpherence() {
return $this->selectedConpherence;
}
public function setTransactions(array $transactions) {
assert_instances_of($transactions, 'ConpherenceTransaction');
$this->transactions = $transactions;
return $this;
}
public function getTransactions() {
return $this->transactions;
}
public function setVisible($visible) {
$this->visible = $visible;
return $this;
}
public function getVisible() {
return $this->visible;
}
public function setInitialLoad($bool) {
$this->initialLoad = $bool;
return $this;
}
public function getInitialLoad() {
return $this->initialLoad;
}
public function setPolicyObjects(array $objects) {
assert_instances_of($objects, 'PhabricatorPolicy');
$this->policyObjects = $objects;
return $this;
}
public function getPolicyObjects() {
return $this->policyObjects;
}
public function setQuicksandConfig(array $config) {
$this->quicksandConfig = $config;
return $this;
}
public function getQuicksandConfig() {
return $this->quicksandConfig;
}
protected function getTagAttributes() {
if ($this->getVisible()) {
$style = null;
} else {
$style = 'display: none;';
}
$classes = array('conpherence-durable-column');
if ($this->getInitialLoad()) {
$classes[] = 'loading';
}
return array(
'id' => 'conpherence-durable-column',
'class' => implode(' ', $classes),
'style' => $style,
'sigil' => 'conpherence-durable-column',
);
}
protected function getTagContent() {
$column_key = PhabricatorUserPreferences::PREFERENCE_CONPHERENCE_COLUMN;
require_celerity_resource('font-source-sans-pro');
Javelin::initBehavior(
'durable-column',
array(
'visible' => $this->getVisible(),
'settingsURI' => '/settings/adjust/?key='.$column_key,
'quicksandConfig' => $this->getQuicksandConfig(),
));
$policies = array();
$conpherences = $this->getConpherences();
foreach ($conpherences as $conpherence) {
if (!$conpherence->getIsRoom()) {
continue;
}
$policies[] = $conpherence->getViewPolicy();
}
$policy_objects = array();
if ($policies) {
$policy_objects = id(new PhabricatorPolicyQuery())
->setViewer($this->getUser())
->withPHIDs($policies)
->execute();
}
$this->setPolicyObjects($policy_objects);
$classes = array();
$classes[] = 'conpherence-durable-column-header';
$classes[] = 'sprite-main-header';
$classes[] = 'main-header-'.PhabricatorEnv::getEnvConfig('ui.header-color');
$loading_mask = phutil_tag(
'div',
array(
'class' => 'loading-mask',
),
'');
$header = phutil_tag(
'div',
array(
'class' => implode(' ', $classes),
),
$this->buildHeader());
$icon_bar = phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-icon-bar',
),
$this->buildIconBar());
$transactions = $this->buildTransactions();
$content = javelin_tag(
'div',
array(
'class' => 'conpherence-durable-column-main',
'sigil' => 'conpherence-durable-column-main',
),
phutil_tag(
'div',
array(
'id' => 'conpherence-durable-column-content',
'class' => 'conpherence-durable-column-frame',
),
javelin_tag(
'div',
array(
'class' => 'conpherence-durable-column-transactions',
'sigil' => 'conpherence-durable-column-transactions',
),
$transactions)));
$input = $this->buildTextInput();
$footer = phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-footer',
),
array(
$this->buildSendButton(),
phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-status',
),
$this->buildStatusText()),
));
return array(
$loading_mask,
$header,
javelin_tag(
'div',
array(
'class' => 'conpherence-durable-column-body',
'sigil' => 'conpherence-durable-column-body',
),
array(
$icon_bar,
$content,
$input,
$footer,
)),
);
}
private function getPolicyIcon(
ConpherenceThread $conpherence,
array $policy_objects) {
assert_instances_of($policy_objects, 'PhabricatorPolicy');
$icon = null;
if ($conpherence->getIsRoom()) {
$icon = $conpherence->getPolicyIconName($policy_objects);
$icon = id(new PHUIIconView())
->addClass('mmr')
->setIconFont($icon);
}
return $icon;
}
private function buildIconBar() {
$icons = array();
$selected_conpherence = $this->getSelectedConpherence();
$conpherences = $this->getConpherences();
foreach ($conpherences as $conpherence) {
$classes = array('conpherence-durable-column-thread-icon');
if ($selected_conpherence->getID() == $conpherence->getID()) {
$classes[] = 'selected';
}
$data = $conpherence->getDisplayData($this->getUser());
$icon = $this->getPolicyIcon($conpherence, $this->getPolicyObjects());
$thread_title = phutil_tag(
'span',
array(),
array(
$icon,
- $data['js_title'],
+ $data['title'],
));
$image = $data['image'];
Javelin::initBehavior('phabricator-tooltips');
$icons[] =
javelin_tag(
'a',
array(
'href' => '/conpherence/columnview/',
'class' => implode(' ', $classes),
'sigil' => 'conpherence-durable-column-thread-icon has-tooltip',
'meta' => array(
'threadID' => $conpherence->getID(),
'threadTitle' => hsprintf('%s', $thread_title),
- 'tip' => $data['js_title'],
+ 'tip' => $data['title'],
'align' => 'S',
),
),
phutil_tag(
'span',
array(
'style' => 'background-image: url('.$image.')',
),
''));
}
$icons[] = $this->buildSearchButton();
return $icons;
}
private function buildSearchButton() {
return phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-search-button',
),
id(new PHUIButtonBarView())
->addButton(
id(new PHUIButtonView())
->setTag('a')
->setHref('/conpherence/search/')
->setColor(PHUIButtonView::GREY)
->setIcon(
id(new PHUIIconView())
->setIconFont('fa-search'))));
}
private function buildHeader() {
$conpherence = $this->getSelectedConpherence();
if (!$conpherence) {
$header = null;
$settings_button = null;
$settings_menu = null;
} else {
$bubble_id = celerity_generate_unique_node_id();
$dropdown_id = celerity_generate_unique_node_id();
$settings_list = new PHUIListView();
$header_actions = $this->getHeaderActionsConfig($conpherence);
foreach ($header_actions as $action) {
$settings_list->addMenuItem(
id(new PHUIListItemView())
->setHref($action['href'])
->setName($action['name'])
->setIcon($action['icon'])
->setDisabled($action['disabled'])
->addSigil('conpherence-durable-column-header-action')
->setMetadata(array(
'action' => $action['key'],
)));
}
$settings_menu = phutil_tag(
'div',
array(
'id' => $dropdown_id,
'class' => 'phabricator-main-menu-dropdown phui-list-sidenav '.
'conpherence-settings-dropdown',
'sigil' => 'phabricator-notification-menu',
'style' => 'display: none',
),
$settings_list);
Javelin::initBehavior(
'aphlict-dropdown',
array(
'bubbleID' => $bubble_id,
'dropdownID' => $dropdown_id,
'local' => true,
'containerDivID' => 'conpherence-durable-column',
));
$item = id(new PHUIListItemView())
->setName(pht('Settings'))
->setIcon('fa-bars')
->addClass('core-menu-item')
->addSigil('conpherence-settings-menu')
->setID($bubble_id)
->setHref('#')
->setAural(pht('Settings'))
->setOrder(300);
$settings_button = id(new PHUIListView())
->addMenuItem($item)
->addClass('phabricator-dark-menu')
->addClass('phabricator-application-menu');
$data = $conpherence->getDisplayData($this->getUser());
$header = phutil_tag(
'span',
array(),
array(
$this->getPolicyIcon($conpherence, $this->getPolicyObjects()),
$data['title'],
));
}
return
phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-header',
),
array(
javelin_tag(
'div',
array(
'sigil' => 'conpherence-durable-column-header-text',
'class' => 'conpherence-durable-column-header-text',
),
$header),
$settings_button,
$settings_menu,
));
}
private function getHeaderActionsConfig(ConpherenceThread $conpherence) {
if ($conpherence->getIsRoom()) {
$rename_label = pht('Edit Room');
} else {
$rename_label = pht('Rename Thread');
}
$can_edit = PhabricatorPolicyFilter::hasCapability(
$this->getUser(),
$conpherence,
PhabricatorPolicyCapability::CAN_EDIT);
return array(
array(
'name' => pht('Add Participants'),
'disabled' => !$can_edit,
'href' => '/conpherence/update/'.$conpherence->getID().'/',
'icon' => 'fa-plus',
'key' => ConpherenceUpdateActions::ADD_PERSON,
),
array(
'name' => $rename_label,
'disabled' => !$can_edit,
'href' => '/conpherence/update/'.$conpherence->getID().'/?nopic',
'icon' => 'fa-pencil',
'key' => ConpherenceUpdateActions::METADATA,
),
array(
'name' => pht('View in Conpherence'),
'disabled' => false,
'href' => '/'.$conpherence->getMonogram(),
'icon' => 'fa-comments',
'key' => 'go_conpherence',
),
array(
'name' => pht('Hide Column'),
'disabled' => false,
'href' => '#',
'icon' => 'fa-times',
'key' => 'hide_column',
),
);
}
private function buildTransactions() {
$conpherence = $this->getSelectedConpherence();
if (!$conpherence) {
if (!$this->getVisible() || $this->getInitialLoad()) {
return pht('Loading...');
}
return array(
phutil_tag(
'div',
array(
'class' => 'mmb',
),
pht('You do not have any messages yet.')),
javelin_tag(
'a',
array(
'href' => '/conpherence/new/',
'class' => 'button grey',
'sigil' => 'workflow',
),
pht('Send a Message')),
);
}
$data = ConpherenceTransactionRenderer::renderTransactions(
$this->getUser(),
$conpherence,
$full_display = false);
$messages = ConpherenceTransactionRenderer::renderMessagePaneContent(
$data['transactions'],
$data['oldest_transaction_id'],
$data['newest_transaction_id']);
return $messages;
}
private function buildTextInput() {
$conpherence = $this->getSelectedConpherence();
if (!$conpherence) {
return null;
}
$draft = $this->getDraft();
$draft_value = null;
if ($draft) {
$draft_value = $draft->getDraft();
}
$textarea_id = celerity_generate_unique_node_id();
$textarea = javelin_tag(
'textarea',
array(
'id' => $textarea_id,
'name' => 'text',
'class' => 'conpherence-durable-column-textarea',
'sigil' => 'conpherence-durable-column-textarea',
'placeholder' => pht('Send a message...'),
),
$draft_value);
Javelin::initBehavior(
'aphront-drag-and-drop-textarea',
array(
'target' => $textarea_id,
'activatedClass' => 'aphront-textarea-drag-and-drop',
'uri' => '/file/dropupload/',
));
$id = $conpherence->getID();
return phabricator_form(
$this->getUser(),
array(
'method' => 'POST',
'action' => '/conpherence/update/'.$id.'/',
'sigil' => 'conpherence-message-form',
),
array(
$textarea,
phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => 'action',
'value' => ConpherenceUpdateActions::MESSAGE,
)),
));
}
private function buildStatusText() {
return null;
}
private function buildSendButton() {
$conpherence = $this->getSelectedConpherence();
if (!$conpherence) {
return null;
}
return javelin_tag(
'button',
array(
'class' => 'grey',
'sigil' => 'conpherence-send-message',
),
pht('Send'));
}
}
diff --git a/src/applications/conpherence/view/ConpherenceThreadListView.php b/src/applications/conpherence/view/ConpherenceThreadListView.php
index 532bb799b4..be8c6e4558 100644
--- a/src/applications/conpherence/view/ConpherenceThreadListView.php
+++ b/src/applications/conpherence/view/ConpherenceThreadListView.php
@@ -1,281 +1,281 @@
<?php
final class ConpherenceThreadListView extends AphrontView {
const SEE_MORE_LIMIT = 5;
private $baseURI;
private $threads;
public function setThreads(array $threads) {
assert_instances_of($threads, 'ConpherenceThread');
$this->threads = $threads;
return $this;
}
public function setBaseURI($base_uri) {
$this->baseURI = $base_uri;
return $this;
}
public function render() {
require_celerity_resource('conpherence-menu-css');
$menu = id(new PHUIListView())
->addClass('conpherence-menu')
->setID('conpherence-menu');
$policy_objects = ConpherenceThread::loadPolicyObjects(
$this->getUser(),
$this->threads);
$grouped = mgroup($this->threads, 'getIsRoom');
$rooms = idx($grouped, 1, array());
$this->addRoomsToMenu($menu, $rooms, $policy_objects);
$messages = idx($grouped, 0, array());
$this->addMessagesToMenu($menu, $messages);
return $menu;
}
public function renderSingleThread(ConpherenceThread $thread) {
$policy_objects = id(new PhabricatorPolicyQuery())
->setViewer($this->getUser())
->setObject($thread)
->execute();
return $this->renderThread($thread, $policy_objects);
}
public function renderThreadsHTML() {
$thread_html = array();
foreach ($this->threads as $thread) {
$thread_html[] = $this->renderSingleThread($thread);
}
return phutil_implode_html('', $thread_html);
}
private function renderThreadItem(
ConpherenceThread $thread,
$policy_objects = array()) {
return id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_CUSTOM)
->setName($this->renderThread($thread, $policy_objects));
}
private function renderThread(
ConpherenceThread $thread,
array $policy_objects) {
$user = $this->getUser();
$uri = '/'.$thread->getMonogram();
$data = $thread->getDisplayData($user);
$icon = null;
if ($thread->getIsRoom()) {
$icon = id(new PHUIIconView())
->addClass('msr')
->setIconFont($thread->getPolicyIconName($policy_objects));
}
$title = phutil_tag(
'span',
array(),
array(
$icon,
$data['title'],
));
$subtitle = $data['subtitle'];
$unread_count = $data['unread_count'];
$epoch = $data['epoch'];
$image = $data['image'];
$dom_id = $thread->getPHID().'-nav-item';
$glyph_pref = PhabricatorUserPreferences::PREFERENCE_TITLES;
$preferences = $user->loadPreferences();
if ($preferences->getPreference($glyph_pref) == 'glyph') {
$glyph = id(new PhabricatorConpherenceApplication())
->getTitleGlyph().' ';
} else {
$glyph = null;
}
return id(new ConpherenceMenuItemView())
->setUser($user)
->setTitle($title)
->setSubtitle($subtitle)
->setHref($uri)
->setEpoch($epoch)
->setImageURI($image)
->setUnreadCount($unread_count)
->setID($thread->getPHID().'-nav-item')
->addSigil('conpherence-menu-click')
->setMetadata(
array(
- 'title' => $glyph.$data['js_title'],
+ 'title' => $glyph.$data['title'],
'id' => $dom_id,
'threadID' => $thread->getID(),
));
}
private function addRoomsToMenu(
PHUIListView $menu,
array $rooms,
array $policy_objects) {
$header = $this->renderMenuItemHeader(
pht('Rooms'),
'conpherence-room-list-header');
$header->appendChild(
id(new PHUIIconView())
->setIconFont('fa-search')
->setHref('/conpherence/search/')
->setText(pht('Search')));
$menu->addMenuItem($header);
if (empty($rooms)) {
$join_item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LINK)
->setHref('/conpherence/search/')
->setName(pht('Join a Room'));
$menu->addMenuItem($join_item);
$create_item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LINK)
->setHref('/conpherence/room/new/')
->setWorkflow(true)
->setName(pht('Create a Room'));
$menu->addMenuItem($create_item);
return $menu;
}
$this->addThreadsToMenu($menu, $rooms, $policy_objects);
return $menu;
}
private function addMessagesToMenu(
PHUIListView $menu,
array $conpherences) {
$header = $this->renderMenuItemHeader(
pht('Messages'),
'conpherence-message-list-header');
$menu->addMenuItem($header);
if (empty($conpherences)) {
$menu->addMenuItem($this->getNoMessagesMenuItem());
return $menu;
}
$this->addThreadsToMenu($menu, $conpherences, array());
return $menu;
}
private function addThreadsToMenu(
PHUIListView $menu,
array $threads,
array $policy_objects) {
// If we have self::SEE_MORE_LIMIT or less, we can just render
// all the threads at once. Otherwise, we render a "See more"
// UI element, which toggles a show / hide on the remaining rooms
$show_threads = $threads;
$more_threads = array();
if (count($threads) > self::SEE_MORE_LIMIT) {
$show_threads = array_slice($threads, 0, self::SEE_MORE_LIMIT);
$more_threads = array_slice($threads, self::SEE_MORE_LIMIT);
}
$is_room = false;
foreach ($show_threads as $thread) {
$item = $this->renderThreadItem($thread, $policy_objects);
$menu->addMenuItem($item);
$is_room = $thread->getIsRoom();
}
if ($more_threads) {
if ($is_room) {
$search_uri = '/conpherence/search/query/participant/';
$sigil = 'more-room';
} else {
$search_uri = '/conpherence/search/query/messages/';
$sigil = 'more-message';
}
$more_item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LINK)
->setHref($search_uri)
->addSigil('conpherence-menu-see-more')
->setMetadata(array('moreSigil' => $sigil))
->setName(pht('See More'));
$menu->addMenuItem($more_item);
$show_more_threads = $more_threads;
$even_more_threads = array();
if (count($more_threads) > self::SEE_MORE_LIMIT) {
$show_more_threads = array_slice(
$more_threads,
0,
self::SEE_MORE_LIMIT);
$even_more_threads = array_slice(
$more_threads,
self::SEE_MORE_LIMIT);
}
foreach ($show_more_threads as $thread) {
$item = $this->renderThreadItem($thread, $policy_objects)
->addSigil($sigil)
->addClass('hidden');
$menu->addMenuItem($item);
}
if ($even_more_threads) {
// kick them to application search here
$even_more_item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LINK)
->setHref($search_uri)
->addSigil($sigil)
->addClass('hidden')
->setName(pht('See More'));
$menu->addMenuItem($even_more_item);
}
}
return $menu;
}
private function renderMenuItemHeader($title, $class = null) {
$item = id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_LABEL)
->setName($title)
->addClass($class);
return $item;
}
private function getNoMessagesMenuItem() {
$message = phutil_tag(
'div',
array(
'class' => 'no-conpherences-menu-item',
),
pht('No Messages'));
return id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_CUSTOM)
->setName($message);
}
private function getNoRoomsMenuItem() {
$message = phutil_tag(
'div',
array(
'class' => 'no-conpherences-menu-item',
),
pht('No Rooms'));
return id(new PHUIListItemView())
->setType(PHUIListItemView::TYPE_CUSTOM)
->setName($message);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 18:45 (4 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1127540
Default Alt Text
(40 KB)

Event Timeline