2013-01-25 02:23:05 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @group conpherence
|
|
|
|
*/
|
|
|
|
abstract class ConpherenceController extends PhabricatorController {
|
|
|
|
private $conpherences;
|
|
|
|
private $selectedConpherencePHID;
|
|
|
|
private $readConpherences;
|
|
|
|
private $unreadConpherences;
|
|
|
|
|
|
|
|
public function setUnreadConpherences(array $conpherences) {
|
|
|
|
assert_instances_of($conpherences, 'ConpherenceThread');
|
|
|
|
$this->unreadConpherences = $conpherences;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
public function getUnreadConpherences() {
|
|
|
|
return $this->unreadConpherences;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setReadConpherences(array $conpherences) {
|
|
|
|
assert_instances_of($conpherences, 'ConpherenceThread');
|
|
|
|
$this->readConpherences = $conpherences;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
public function getReadConpherences() {
|
|
|
|
return $this->readConpherences;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setSelectedConpherencePHID($phid) {
|
|
|
|
$this->selectedConpherencePHID = $phid;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
public function getSelectedConpherencePHID() {
|
|
|
|
return $this->selectedConpherencePHID;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Try for a full set of unread conpherences, and if we fail
|
|
|
|
* load read conpherences. Additional conpherences in either category
|
|
|
|
* are loaded asynchronously.
|
|
|
|
*/
|
|
|
|
public function loadStartingConpherences($current_selection_epoch = null) {
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
|
|
|
|
$read_participant_query = id(new ConpherenceParticipantQuery())
|
|
|
|
->withParticipantPHIDs(array($user->getPHID()));
|
|
|
|
$read_status = ConpherenceParticipationStatus::UP_TO_DATE;
|
|
|
|
if ($current_selection_epoch) {
|
|
|
|
$read_one = $read_participant_query
|
|
|
|
->withParticipationStatus($read_status)
|
|
|
|
->withDateTouched($current_selection_epoch, '>')
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$read_two = $read_participant_query
|
|
|
|
->withDateTouched($current_selection_epoch, '<=')
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$read = array_merge($read_one, $read_two);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
$read = $read_participant_query
|
|
|
|
->withParticipationStatus($read_status)
|
|
|
|
->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
$unread_status = ConpherenceParticipationStatus::BEHIND;
|
2013-01-27 02:14:58 +01:00
|
|
|
$unread = id(new ConpherenceParticipantQuery())
|
|
|
|
->withParticipantPHIDs(array($user->getPHID()))
|
2013-01-25 02:23:05 +01:00
|
|
|
->withParticipationStatus($unread_status)
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$all_participation = $unread + $read;
|
|
|
|
$all_conpherence_phids = array_keys($all_participation);
|
|
|
|
$all_conpherences = id(new ConpherenceThreadQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withPHIDs($all_conpherence_phids)
|
|
|
|
->execute();
|
|
|
|
$unread_conpherences = array_select_keys(
|
|
|
|
$all_conpherences,
|
|
|
|
array_keys($unread)
|
|
|
|
);
|
|
|
|
$this->setUnreadConpherences($unread_conpherences);
|
|
|
|
|
|
|
|
$read_conpherences = array_select_keys(
|
|
|
|
$all_conpherences,
|
|
|
|
array_keys($read)
|
|
|
|
);
|
|
|
|
$this->setReadConpherences($read_conpherences);
|
|
|
|
|
|
|
|
if (!$this->getSelectedConpherencePHID()) {
|
|
|
|
$this->setSelectedConpherencePHID(reset($all_conpherence_phids));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildSideNavView($filter = null) {
|
|
|
|
require_celerity_resource('conpherence-menu-css');
|
|
|
|
$unread_conpherences = $this->getUnreadConpherences();
|
|
|
|
$read_conpherences = $this->getReadConpherences();
|
|
|
|
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
|
|
|
|
$menu = new PhabricatorMenuView();
|
|
|
|
$nav = AphrontSideNavFilterView::newFromMenu($menu);
|
|
|
|
$nav->addClass('conpherence-menu');
|
|
|
|
$nav->setMenuID('conpherence-menu');
|
|
|
|
|
2013-01-29 19:20:17 +01:00
|
|
|
$nav->addButton(
|
2013-01-25 02:23:05 +01:00
|
|
|
'new',
|
2013-01-29 19:20:17 +01:00
|
|
|
pht('New Conversation'),
|
2013-01-25 02:23:05 +01:00
|
|
|
$this->getApplicationURI('new/')
|
|
|
|
);
|
|
|
|
$nav->addLabel(pht('Unread'));
|
|
|
|
$nav = $this->addConpherencesToNav($unread_conpherences, $nav);
|
|
|
|
|
|
|
|
$nav->addLabel(pht('Read'));
|
|
|
|
$nav = $this->addConpherencesToNav($read_conpherences, $nav, true);
|
|
|
|
|
|
|
|
$nav->selectFilter($filter);
|
|
|
|
|
|
|
|
return $nav;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function addConpherencesToNav(
|
|
|
|
array $conpherences,
|
|
|
|
AphrontSideNavFilterView $nav,
|
|
|
|
$read = false) {
|
|
|
|
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
foreach ($conpherences as $conpherence) {
|
|
|
|
$uri = $this->getApplicationURI('view/'.$conpherence->getID().'/');
|
2013-02-06 23:03:52 +01:00
|
|
|
$data = $conpherence->getDisplayData(
|
|
|
|
$user,
|
|
|
|
null
|
|
|
|
);
|
2013-01-25 02:23:05 +01:00
|
|
|
$title = $data['title'];
|
|
|
|
$subtitle = $data['subtitle'];
|
|
|
|
$unread_count = $data['unread_count'];
|
|
|
|
$epoch = $data['epoch'];
|
|
|
|
$image = $data['image'];
|
|
|
|
$snippet = $data['snippet'];
|
|
|
|
|
|
|
|
$item = id(new ConpherenceMenuItemView())
|
|
|
|
->setUser($user)
|
|
|
|
->setTitle($title)
|
|
|
|
->setSubtitle($subtitle)
|
|
|
|
->setHref($uri)
|
|
|
|
->setEpoch($epoch)
|
|
|
|
->setImageURI($image)
|
|
|
|
->setMessageText($snippet)
|
|
|
|
->setUnreadCount($unread_count)
|
|
|
|
->setID($conpherence->getPHID())
|
|
|
|
->addSigil('conpherence-menu-click')
|
|
|
|
->setMetadata(array('id' => $conpherence->getID()));
|
|
|
|
if ($this->getSelectedConpherencePHID() == $conpherence->getPHID()) {
|
|
|
|
$item->addClass('conpherence-selected');
|
|
|
|
$item->addClass('hide-unread-count');
|
|
|
|
}
|
Fix every HTML issue I could find
Summary:
I attempted to test every interface. I probably missed some stuff, but I at least have some level of confidence that the `phutil_tag` branch is fairly stable.
Fixed these issues:
[1] Fixed a Herald issue with object links in transcripts. Some actions return
links; this was previously hard-coded.
[2] DarkConsole refactoring created an issue where the "`" event handler registered too many times.
[3] Fixed a bug where `strlen($value)` was being checked, but fields may now return array(). Possibly we should implement phutil_is_empty_html() or similar.
[4] Fixed a undefined variable issue for image edit transactions.
[5] Fixed an issue with rendering participant transactions. This required phutil_safe_html() because `pht()` can't handle `array()` for `%s`.
[6] Fixed an issue where feed was entirely overescaped by reverting an overly ambitious render_tag -> tag.
[7] Fixed an issue with strict tables and inserting `''` instead of `0` into an integer column.
[8] Fixed an issue where • was shown escaped.
[9] Fixed an issue where "no data" was overescaped.
[10] Fixed an issue with strict tables and inserting `''` instead of `0` into an integer column.
[11] Fixed an issue with strict tables and inserting `''`.
[12] Fixed an issue with missing space after ":" for mini panels.
Encountered (but did not fix) these issues:
[X1] "e" works incorrectly on comments you are not allowed to edit. Did not fix.
[X2] Coverage currently interacts incorrectly with "--everything" for Phutil tests.
Test Plan:
- Viewed Differential.
- Created a diff via copy/paste.
- Viewed standalone diff.
- Jumped to diff via changeset table.
- Created a revision.
- Updated revision.
- Added a comment.
- Edited revision dependencies.
- Edited revision tasks.
- Viewed MetaMTA transcripts.
- Viewed Herald transcripts [1].
- Downloaded raw diff.
- Flagged / unflagged revision.
- Added/edited/deleted inline comment.
- Collapsed/expanded file.
- Did show raw left.
- Did show raw right.
- Checked previews for available actions.
- Clicked remarkup buttons
- Used filetree view.
- Used keyboard: F, j, k, J, K, n, p, t, h, "?" [2] [X1].
- Created a meme.
- Uploaded a file via drag and drop.
- Viewed a revision with no reviewers.
- Viewed a revision with >100 files.
- Viewed various other revisions [3].
- Viewed an image diff.
- Added image diff inline comments.
- Viewed Maniphest.
- Ran various queries.
- Created task.
- Created similar task.
- Added comments to tasks.
- Ran custom query.
- Saved custom query.
- Edited custom queries.
- Drag-reordered tasks.
- Batch edited tasks.
- Exported tasks to excel.
- Looked at reports (issue in T2311 notwithstanding).
- Viewed Diffusion.
- Browsed Git, SVN, HG repositories.
- Looked at history, browse, change, commit views.
- Viewed audit.
- Performed various audit searches.
- Viewed Paste.
- Performed paste searches.
- Created, edited, forked paste.
- Viewed Phriction.
- Edited a page.
- Viewed edit history.
- Used search typeahead to search for user / application.
- Used search to search for text.
- Viewed Phame.
- Viewed Blog, Post.
- Viewed live post.
- Published/unpublished post.
- Previewed post.
- Viewed Pholio.
- Edited/commented mock.
- Viewed ponder.
- Viewed question.
- Added answer/comment.
- Viewed Diviner.
- Viewed Conpherence [4] [5].
- Made Conpherence updates.
- Viewed calendar.
- Created status.
- Viewed status.
- Viewed Feed [6].
- Viewed Projects.
- Viewed project detail.
- Edited project.
- Viewed Owners.
- Viewed package detail.
- Edited package [7].
- Viewed flags.
- Edited flag.
- Deleted flag.
- Viewed Herald.
- Viewed rules.
- Created rule.
- Edited rule.
- Viewed edit log.
- Viewed transcripts.
- Inspected a transcript.
- Viewed People.
- Viewed list.
- Administrated user.
- Checked username/delete stuff.
- Looked at create/import LDAP/activity logs.
- Looked at a user profile.
- Looked at user about page.
- Looked at Repositories.
- Edited repository.
- Edited arcanist project.
- Looked at daemons.
- Looked at all daemons [8].
- Viewed combined log.
- Looked at configuration.
- Edited configuration.
- Looked at setup issues [9].
- Looked at current settings.
- Looked at application list.
- Installed / uninstalled applications [10].
- Looked at mailing lists.
- Created a mailing list.
- Edited a mailing list.
- Looked at sent mail.
- Looked at received mail.
- Looked at send/receive tests.
- Looked at settings.
- Clicked through all the panels.
- Looked at slowvote.
- Created a slowvote [11].
- Voted in a slowvote.
- Looked at Macro.
- Created a macro.
- Edited a macro.
- Commented on a macro.
- Looked at Countdown.
- Created a Countdown.
- Looked at it.
- Looked at Drydock.
- Poked around a bit.
- Looked at Fact.
- Poked around a bit.
- Looked at files.
- Looked at a file.
- Uploaded a file.
- Looked at Conduit.
- Made a Conduit call.
- Looked at UIExamples.
- Looked at PHPAST.
- Looked at PHIDs.
- Looked at notification menu.
- Looked at notification detail.
- Logged out.
- Logged in.
- Looked at homepage [12].
- Ran `arc unit --everything --no-coverage` [X2].
Reviewers: vrana, btrahan
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2432
Differential Revision: https://secure.phabricator.com/D4807
2013-02-05 02:06:34 +01:00
|
|
|
|
|
|
|
// TODO: [HTML] Clean this up when we clean up HTML stuff in Conpherence.
|
|
|
|
$nav->addCustomBlock(phutil_safe_html($item->render()));
|
2013-01-25 02:23:05 +01:00
|
|
|
}
|
|
|
|
if (empty($conpherences) || $read) {
|
|
|
|
$nav->addCustomBlock($this->getNoConpherencesBlock());
|
|
|
|
}
|
|
|
|
|
|
|
|
return $nav;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getNoConpherencesBlock() {
|
2013-01-25 14:50:50 +01:00
|
|
|
return phutil_tag(
|
2013-01-25 02:23:05 +01:00
|
|
|
'div',
|
|
|
|
array(
|
|
|
|
'class' => 'no-conpherences-menu-item'
|
|
|
|
),
|
2013-01-25 14:50:50 +01:00
|
|
|
pht('No more conpherences.'));
|
2013-01-25 02:23:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function buildApplicationMenu() {
|
|
|
|
return $this->buildSideNavView()->getMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function buildApplicationCrumbs() {
|
|
|
|
$crumbs = parent::buildApplicationCrumbs();
|
|
|
|
|
|
|
|
$crumbs
|
|
|
|
->addAction(
|
|
|
|
id(new PhabricatorMenuItemView())
|
2013-01-29 19:20:17 +01:00
|
|
|
->setName(pht('New Conversation'))
|
2013-01-25 02:23:05 +01:00
|
|
|
->setHref($this->getApplicationURI('new/'))
|
|
|
|
->setIcon('create')
|
|
|
|
)
|
|
|
|
->addCrumb(
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
->setName(pht('Conpherence'))
|
|
|
|
);
|
|
|
|
|
|
|
|
return $crumbs;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function initJavelinBehaviors() {
|
|
|
|
|
|
|
|
Javelin::initBehavior('conpherence-menu',
|
|
|
|
array(
|
|
|
|
'base_uri' => $this->getApplicationURI(''),
|
|
|
|
'header' => 'conpherence-header-pane',
|
|
|
|
'messages' => 'conpherence-messages',
|
|
|
|
'widgets_pane' => 'conpherence-widget-pane',
|
|
|
|
'form_pane' => 'conpherence-form',
|
2013-02-05 20:58:19 +01:00
|
|
|
'menu_pane' => 'conpherence-menu',
|
2013-01-25 02:23:05 +01:00
|
|
|
'fancy_ajax' => (bool) $this->getSelectedConpherencePHID()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
Javelin::initBehavior('conpherence-init',
|
|
|
|
array(
|
|
|
|
'selected_conpherence_id' => $this->getSelectedConpherencePHID(),
|
|
|
|
'menu_pane' => 'conpherence-menu',
|
|
|
|
'messages_pane' => 'conpherence-message-pane',
|
|
|
|
'messages' => 'conpherence-messages',
|
|
|
|
'widgets_pane' => 'conpherence-widget-pane',
|
|
|
|
'form_pane' => 'conpherence-form'
|
|
|
|
)
|
|
|
|
);
|
2013-02-06 23:03:52 +01:00
|
|
|
Javelin::initBehavior('conpherence-drag-and-drop-photo',
|
|
|
|
array(
|
|
|
|
'target' => 'conpherence-header-pane',
|
|
|
|
'form_pane' => 'conpherence-form',
|
|
|
|
'upload_uri' => '/file/dropupload/',
|
|
|
|
'activated_class' => 'conpherence-header-upload-photo',
|
|
|
|
)
|
|
|
|
);
|
2013-01-25 02:23:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|