Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2893618
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
40 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment