Page MenuHomePhabricator

D11968.diff
No OneTemporary

D11968.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,8 +7,8 @@
*/
return array(
'names' => array(
- 'core.pkg.css' => 'd9fa6161',
- 'core.pkg.js' => '23d653bb',
+ 'core.pkg.css' => '1a530a25',
+ 'core.pkg.js' => 'a77025a1',
'darkconsole.pkg.js' => '8ab24e01',
'differential.pkg.css' => '4c3242f8',
'differential.pkg.js' => '7b5a4aa4',
@@ -44,7 +44,7 @@
'rsrc/css/application/config/config-welcome.css' => '6abd79be',
'rsrc/css/application/config/setup-issue.css' => '22270af2',
'rsrc/css/application/config/unhandled-exception.css' => '37d4f9a2',
- 'rsrc/css/application/conpherence/durable-column.css' => '12846d25',
+ 'rsrc/css/application/conpherence/durable-column.css' => '3b836442',
'rsrc/css/application/conpherence/menu.css' => '73774137',
'rsrc/css/application/conpherence/message-pane.css' => '17a9517f',
'rsrc/css/application/conpherence/notification.css' => '04a6e10a',
@@ -107,7 +107,7 @@
'rsrc/css/core/core.css' => 'c8c5ecd2',
'rsrc/css/core/remarkup.css' => '2dbff225',
'rsrc/css/core/syntax.css' => '56c1ba38',
- 'rsrc/css/core/z-index.css' => '8239495e',
+ 'rsrc/css/core/z-index.css' => '9ec70c03',
'rsrc/css/diviner/diviner-shared.css' => '38813222',
'rsrc/css/font/font-awesome.css' => 'ae9a7b4d',
'rsrc/css/font/font-source-sans-pro.css' => '0d859f60',
@@ -346,12 +346,12 @@
'rsrc/image/texture/table_header_hover.png' => '038ec3b9',
'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
'rsrc/js/application/aphlict/Aphlict.js' => '2be71d56',
- 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => '335470d7',
+ 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'cc2d9c80',
'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '851f167c',
'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'ea681761',
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de',
- 'rsrc/js/application/conpherence/behavior-durable-column.js' => '3d86ed6e',
+ 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'dc9fb293',
'rsrc/js/application/conpherence/behavior-menu.js' => '869e3445',
'rsrc/js/application/conpherence/behavior-pontificate.js' => '86df5915',
'rsrc/js/application/conpherence/behavior-widget-pane.js' => '40b1ff90',
@@ -513,7 +513,7 @@
'changeset-view-manager' => '5eb5b98c',
'config-options-css' => '7fedf08b',
'config-welcome-css' => '6abd79be',
- 'conpherence-durable-column-view' => '12846d25',
+ 'conpherence-durable-column-view' => '3b836442',
'conpherence-menu-css' => '73774137',
'conpherence-message-pane-css' => '17a9517f',
'conpherence-notification-css' => '04a6e10a',
@@ -542,7 +542,7 @@
'inline-comment-summary-css' => 'eb5f8e8c',
'javelin-aphlict' => '2be71d56',
'javelin-behavior' => '61cbc29a',
- 'javelin-behavior-aphlict-dropdown' => '335470d7',
+ 'javelin-behavior-aphlict-dropdown' => 'cc2d9c80',
'javelin-behavior-aphlict-listen' => '851f167c',
'javelin-behavior-aphlict-status' => 'ea681761',
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
@@ -584,7 +584,7 @@
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
'javelin-behavior-diffusion-pull-lastmodified' => '2b228192',
'javelin-behavior-doorkeeper-tag' => 'e5822781',
- 'javelin-behavior-durable-column' => '3d86ed6e',
+ 'javelin-behavior-durable-column' => 'dc9fb293',
'javelin-behavior-error-log' => '6882e80a',
'javelin-behavior-fancy-datepicker' => 'c51ae228',
'javelin-behavior-global-drag-and-drop' => '07f199d8',
@@ -759,7 +759,7 @@
'phabricator-uiexample-reactor-select' => 'a155550f',
'phabricator-uiexample-reactor-sendclass' => '1def2711',
'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee',
- 'phabricator-zindex-css' => '8239495e',
+ 'phabricator-zindex-css' => '9ec70c03',
'phame-css' => '88bd4705',
'pholio-css' => '95174bdd',
'pholio-edit-css' => '3ad9d1ee',
@@ -1011,16 +1011,6 @@
'331b1611' => array(
'javelin-install',
),
- '335470d7' => array(
- 'javelin-behavior',
- 'javelin-request',
- 'javelin-stratcom',
- 'javelin-vector',
- 'javelin-dom',
- 'javelin-uri',
- 'javelin-behavior-device',
- 'phabricator-title',
- ),
'3ab51e2c' => array(
'javelin-behavior',
'javelin-behavior-device',
@@ -1037,14 +1027,6 @@
'javelin-util',
'javelin-uri',
),
- '3d86ed6e' => array(
- 'javelin-behavior',
- 'javelin-dom',
- 'javelin-stratcom',
- 'javelin-scrollbar',
- 'javelin-quicksand',
- 'phabricator-keyboard-shortcut',
- ),
'3ee3408b' => array(
'javelin-behavior',
'javelin-behavior-device',
@@ -1751,6 +1733,16 @@
'javelin-stratcom',
'phabricator-phtize',
),
+ 'cc2d9c80' => array(
+ 'javelin-behavior',
+ 'javelin-request',
+ 'javelin-stratcom',
+ 'javelin-vector',
+ 'javelin-dom',
+ 'javelin-uri',
+ 'javelin-behavior-device',
+ 'phabricator-title',
+ ),
'd19198c8' => array(
'javelin-install',
'javelin-dom',
@@ -1790,6 +1782,15 @@
'javelin-dom',
'phabricator-busy',
),
+ 'dc9fb293' => array(
+ 'javelin-behavior',
+ 'javelin-dom',
+ 'javelin-stratcom',
+ 'javelin-scrollbar',
+ 'javelin-quicksand',
+ 'phabricator-keyboard-shortcut',
+ 'javelin-behavior-conpherence-widget-pane',
+ ),
'de2e896f' => array(
'javelin-behavior',
'javelin-dom',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -221,6 +221,7 @@
'ConduitQueryConduitAPIMethod' => 'applications/conduit/method/ConduitQueryConduitAPIMethod.php',
'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
'ConduitTokenGarbageCollector' => 'applications/conduit/garbagecollector/ConduitTokenGarbageCollector.php',
+ 'ConpherenceColumnViewController' => 'applications/conpherence/controller/ConpherenceColumnViewController.php',
'ConpherenceConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceConduitAPIMethod.php',
'ConpherenceConfigOptions' => 'applications/conpherence/config/ConpherenceConfigOptions.php',
'ConpherenceConstants' => 'applications/conpherence/constants/ConpherenceConstants.php',
@@ -263,6 +264,7 @@
'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
'ConpherenceUpdateThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php',
'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
+ 'ConpherenceWidgetConfigConstants' => 'applications/conpherence/constants/ConpherenceWidgetConfigConstants.php',
'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php',
'ConpherenceWidgetView' => 'applications/conpherence/view/ConpherenceWidgetView.php',
'DarkConsoleController' => 'applications/console/controller/DarkConsoleController.php',
@@ -3361,6 +3363,7 @@
'ConduitQueryConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
'ConduitTokenGarbageCollector' => 'PhabricatorGarbageCollector',
+ 'ConpherenceColumnViewController' => 'ConpherenceController',
'ConpherenceConduitAPIMethod' => 'ConduitAPIMethod',
'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions',
'ConpherenceController' => 'PhabricatorController',
@@ -3405,6 +3408,7 @@
'ConpherenceUpdateController' => 'ConpherenceController',
'ConpherenceUpdateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
'ConpherenceViewController' => 'ConpherenceController',
+ 'ConpherenceWidgetConfigConstants' => 'ConpherenceConstants',
'ConpherenceWidgetController' => 'ConpherenceController',
'ConpherenceWidgetView' => 'AphrontView',
'DarkConsoleController' => 'PhabricatorController',
diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
--- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
+++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php
@@ -34,6 +34,7 @@
'' => 'ConpherenceListController',
'thread/(?P<id>[1-9]\d*)/' => 'ConpherenceListController',
'(?P<id>[1-9]\d*)/' => 'ConpherenceViewController',
+ 'columnview/' => 'ConpherenceColumnViewController',
'new/' => 'ConpherenceNewController',
'panel/' => 'ConpherenceNotificationPanelController',
'widget/(?P<id>[1-9]\d*)/' => 'ConpherenceWidgetController',
diff --git a/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php b/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php
@@ -0,0 +1,59 @@
+<?php
+
+final class ConpherenceWidgetConfigConstants extends ConpherenceConstants {
+
+ const UPDATE_URI = '/conpherence/update/';
+
+ public static function getWidgetPaneBehaviorConfig() {
+ return array(
+ 'widgetBaseUpdateURI' => self::UPDATE_URI,
+ 'widgetRegistry' => self::getWidgetRegistry(),
+ );
+ }
+
+ public static function getWidgetRegistry() {
+ return array(
+ 'conpherence-message-pane' => array(
+ 'name' => pht('Thread'),
+ 'icon' => 'fa-comment',
+ 'deviceOnly' => true,
+ 'hasCreate' => false,
+ ),
+ 'widgets-people' => array(
+ 'name' => pht('Participants'),
+ 'icon' => 'fa-users',
+ 'deviceOnly' => false,
+ 'hasCreate' => true,
+ 'createData' => array(
+ 'refreshFromResponse' => true,
+ 'action' => ConpherenceUpdateActions::ADD_PERSON,
+ 'customHref' => null,
+ ),
+ ),
+ 'widgets-files' => array(
+ 'name' => pht('Files'),
+ 'icon' => 'fa-files-o',
+ 'deviceOnly' => false,
+ 'hasCreate' => false,
+ ),
+ 'widgets-calendar' => array(
+ 'name' => pht('Calendar'),
+ 'icon' => 'fa-calendar',
+ 'deviceOnly' => false,
+ 'hasCreate' => true,
+ 'createData' => array(
+ 'refreshFromResponse' => false,
+ 'action' => ConpherenceUpdateActions::ADD_STATUS,
+ 'customHref' => '/calendar/event/create/',
+ ),
+ ),
+ 'widgets-settings' => array(
+ 'name' => pht('Settings'),
+ 'icon' => 'fa-wrench',
+ 'deviceOnly' => false,
+ 'hasCreate' => false,
+ ),
+ );
+ }
+
+}
diff --git a/src/applications/conpherence/controller/ConpherenceColumnViewController.php b/src/applications/conpherence/controller/ConpherenceColumnViewController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conpherence/controller/ConpherenceColumnViewController.php
@@ -0,0 +1,59 @@
+<?php
+
+final class ConpherenceColumnViewController extends
+ ConpherenceController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $user = $request->getUser();
+
+ $conpherence = null;
+ if ($request->getInt('id')) {
+ $conpherence = id(new ConpherenceThreadQuery())
+ ->setViewer($user)
+ ->withIDs(array($request->getInt('id')))
+ ->needTransactions(true)
+ ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT)
+ ->executeOne();
+ } else {
+ // TODO - should be pulling more data than this to build the
+ // icon bar, etc, kind of always
+ $latest_participant = id(new ConpherenceParticipantQuery())
+ ->withParticipantPHIDs(array($user->getPHID()))
+ ->setLimit(1)
+ ->execute();
+ $participant = head($latest_participant);
+ $conpherence = id(new ConpherenceThreadQuery())
+ ->setViewer($user)
+ ->withPHIDs(array($participant->getConpherencePHID()))
+ ->needTransactions(true)
+ ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT)
+ ->executeOne();
+ }
+
+ if (!$conpherence) {
+ return new Aphront404Response();
+ }
+ $this->setConpherence($conpherence);
+
+ $participant = $conpherence->getParticipant($user->getPHID());
+ $transactions = $conpherence->getTransactions();
+ $latest_transaction = head($transactions);
+ $write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
+ $participant->markUpToDate($conpherence, $latest_transaction);
+ unset($write_guard);
+
+ $durable_column = id(new ConpherenceDurableColumnView())
+ ->setUser($user)
+ ->setSelectedConpherence($conpherence)
+ ->setStyle(null);
+
+ $response = array(
+ 'content' => hsprintf('%s', $durable_column),
+ 'threadID' => $conpherence->getID(),
+ 'threadPHID' => $conpherence->getPHID(),
+ 'latestTransactionID' => $latest_transaction->getID(),);
+
+ return id(new AphrontAjaxResponse())->setContent($response);
+ }
+
+}
diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php
--- a/src/applications/conpherence/controller/ConpherenceController.php
+++ b/src/applications/conpherence/controller/ConpherenceController.php
@@ -2,7 +2,15 @@
abstract class ConpherenceController extends PhabricatorController {
- private $conpherences;
+ private $conpherence;
+
+ public function setConpherence(ConpherenceThread $conpherence) {
+ $this->conpherence = $conpherence;
+ return $this;
+ }
+ public function getConpherence() {
+ return $this->conpherence;
+ }
public function buildApplicationMenu() {
$nav = new PHUIListView();
@@ -77,80 +85,4 @@
$crumbs,
));
}
-
- protected function renderConpherenceTransactions(
- ConpherenceThread $conpherence) {
-
- $user = $this->getRequest()->getUser();
- $transactions = $conpherence->getTransactions();
- $oldest_transaction_id = 0;
- $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1;
- if (count($transactions) == $too_many) {
- $last_transaction = end($transactions);
- unset($transactions[$last_transaction->getID()]);
- $oldest_transaction = end($transactions);
- $oldest_transaction_id = $oldest_transaction->getID();
- }
- $transactions = array_reverse($transactions);
- $handles = $conpherence->getHandles();
- $rendered_transactions = array();
- $engine = id(new PhabricatorMarkupEngine())
- ->setViewer($user);
- foreach ($transactions as $key => $transaction) {
- if ($transaction->shouldHide()) {
- unset($transactions[$key]);
- continue;
- }
- if ($transaction->getComment()) {
- $engine->addObject(
- $transaction->getComment(),
- PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
- }
- }
- $engine->process();
- // we're going to insert a dummy date marker transaction for breaks
- // between days. some setup required!
- $previous_transaction = null;
- $date_marker_transaction = id(new ConpherenceTransaction())
- ->setTransactionType(ConpherenceTransactionType::TYPE_DATE_MARKER)
- ->makeEphemeral();
- $date_marker_transaction_view = id(new ConpherenceTransactionView())
- ->setUser($user)
- ->setConpherenceTransaction($date_marker_transaction)
- ->setHandles($handles)
- ->setMarkupEngine($engine);
- foreach ($transactions as $transaction) {
- if ($previous_transaction) {
- $previous_day = phabricator_format_local_time(
- $previous_transaction->getDateCreated(),
- $user,
- 'Ymd');
- $current_day = phabricator_format_local_time(
- $transaction->getDateCreated(),
- $user,
- 'Ymd');
- // date marker transaction time!
- if ($previous_day != $current_day) {
- $date_marker_transaction->setDateCreated(
- $transaction->getDateCreated());
- $rendered_transactions[] = $date_marker_transaction_view->render();
- }
- }
- $rendered_transactions[] = id(new ConpherenceTransactionView())
- ->setUser($user)
- ->setConpherenceTransaction($transaction)
- ->setHandles($handles)
- ->setMarkupEngine($engine)
- ->render();
- $previous_transaction = $transaction;
- }
- $latest_transaction_id = $transaction->getID();
-
- return array(
- 'transactions' => $rendered_transactions,
- 'latest_transaction_id' => $latest_transaction_id,
- 'oldest_transaction_id' => $oldest_transaction_id,
- );
- }
-
}
diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php
--- a/src/applications/conpherence/controller/ConpherenceUpdateController.php
+++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php
@@ -309,7 +309,12 @@
->executeOne();
if ($need_transactions) {
- $data = $this->renderConpherenceTransactions($conpherence);
+ $data = ConpherenceTransactionView::renderTransactions(
+ $user,
+ $conpherence,
+ !$this->getRequest()->getExists('minimal_display'));
+ $participant_obj = $conpherence->getParticipant($user->getPHID());
+ $participant_obj->markUpToDate($conpherence, $data['latest_transaction']);
} else {
$data = array();
}
diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php
--- a/src/applications/conpherence/controller/ConpherenceViewController.php
+++ b/src/applications/conpherence/controller/ConpherenceViewController.php
@@ -3,34 +3,10 @@
final class ConpherenceViewController extends
ConpherenceController {
- private $conpherenceID;
- private $conpherence;
-
- public function setConpherence(ConpherenceThread $conpherence) {
- $this->conpherence = $conpherence;
- return $this;
- }
- public function getConpherence() {
- return $this->conpherence;
- }
-
- public function setConpherenceID($conpherence_id) {
- $this->conpherenceID = $conpherence_id;
- return $this;
- }
- public function getConpherenceID() {
- return $this->conpherenceID;
- }
-
- public function willProcessRequest(array $data) {
- $this->setConpherenceID(idx($data, 'id'));
- }
-
- public function processRequest() {
- $request = $this->getRequest();
+ public function handleRequest(AphrontRequest $request) {
$user = $request->getUser();
- $conpherence_id = $this->getConpherenceID();
+ $conpherence_id = $request->getURIData('id');
if (!$conpherence_id) {
return new Aphront404Response();
}
@@ -53,13 +29,15 @@
$participant = $conpherence->getParticipant($user->getPHID());
$transactions = $conpherence->getTransactions();
- $latest_transaction = end($transactions);
+ $latest_transaction = head($transactions);
$write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
$participant->markUpToDate($conpherence, $latest_transaction);
unset($write_guard);
- $data = $this->renderConpherenceTransactions($conpherence);
- $messages = $this->renderMessagePaneContent(
+ $data = ConpherenceTransactionView::renderTransactions(
+ $user,
+ $conpherence);
+ $messages = ConpherenceTransactionView::renderMessagePaneContent(
$data['transactions'],
$data['oldest_transaction_id']);
if ($before_transaction_id) {
@@ -76,6 +54,12 @@
);
}
+ $title = $conpherence->getTitle();
+ if (!$title) {
+ $title = pht('[No Title]');
+ }
+ $content['title'] = $title;
+
if ($request->isAjax()) {
return id(new AphrontAjaxResponse())->setContent($content);
}
@@ -88,11 +72,7 @@
->setReplyForm($form)
->setRole('thread');
- $title = $conpherence->getTitle();
- if (!$title) {
- $title = pht('[No Title]');
- }
- return $this->buildApplicationPage(
+ return $this->buildApplicationPage(
$layout,
array(
'title' => $title,
@@ -100,29 +80,6 @@
));
}
- private function renderMessagePaneContent(
- array $transactions,
- $oldest_transaction_id) {
-
- $scrollbutton = '';
- if ($oldest_transaction_id) {
- $scrollbutton = javelin_tag(
- 'a',
- array(
- 'href' => '#',
- 'mustcapture' => true,
- 'sigil' => 'show-older-messages',
- 'class' => 'conpherence-show-older-messages',
- 'meta' => array(
- 'oldest_transaction_id' => $oldest_transaction_id,
- ),
- ),
- pht('Show Older Messages'));
- }
-
- return hsprintf('%s%s', $scrollbutton, $transactions);
- }
-
private function renderFormContent($latest_transaction_id) {
$conpherence = $this->getConpherence();
@@ -168,4 +125,5 @@
return $form;
}
+
}
diff --git a/src/applications/conpherence/controller/ConpherenceWidgetController.php b/src/applications/conpherence/controller/ConpherenceWidgetController.php
--- a/src/applications/conpherence/controller/ConpherenceWidgetController.php
+++ b/src/applications/conpherence/controller/ConpherenceWidgetController.php
@@ -2,8 +2,6 @@
final class ConpherenceWidgetController extends ConpherenceController {
- private $conpherenceID;
- private $conpherence;
private $userPreferences;
public function setUserPreferences(PhabricatorUserPreferences $pref) {
@@ -15,33 +13,11 @@
return $this->userPreferences;
}
- public function setConpherence(ConpherenceThread $conpherence) {
- $this->conpherence = $conpherence;
- return $this;
- }
-
- public function getConpherence() {
- return $this->conpherence;
- }
-
- public function setConpherenceID($conpherence_id) {
- $this->conpherenceID = $conpherence_id;
- return $this;
- }
-
- public function getConpherenceID() {
- return $this->conpherenceID;
- }
-
- public function willProcessRequest(array $data) {
- $this->setConpherenceID(idx($data, 'id'));
- }
-
- public function processRequest() {
+ public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$user = $request->getUser();
- $conpherence_id = $this->getConpherenceID();
+ $conpherence_id = $request->getURIData('id');
if (!$conpherence_id) {
return new Aphront404Response();
}
@@ -54,8 +30,25 @@
$this->setUserPreferences($user->loadPreferences());
- $widgets = $this->renderWidgetPaneContent();
- $content = $widgets;
+ switch ($request->getStr('widget')) {
+ case 'widgets-people':
+ $content = $this->renderPeopleWidgetPaneContent();
+ break;
+ case 'widgets-files':
+ $content = $this->renderFileWidgetPaneContent();
+ break;
+ case 'widgets-calendar':
+ $widget = $this->renderCalendarWidgetPaneContent();
+ $content = phutil_implode_html('', $widget);
+ break;
+ case 'widgets-settings':
+ $content = $this->renderSettingsWidgetPaneContent();
+ break;
+ default:
+ $widgets = $this->renderWidgetPaneContent();
+ $content = $widgets;
+ break;
+ }
return id(new AphrontAjaxResponse())->setContent($content);
}
@@ -89,11 +82,8 @@
'id' => 'widgets-people',
'sigil' => 'widgets-people',
),
- id(new ConpherencePeopleWidgetView())
- ->setUser($user)
- ->setConpherence($conpherence)
- ->setUpdateURI($this->getWidgetURI()));
- $widgets[] = javelin_tag(
+ $this->renderPeopleWidgetPaneContent());
+ $widgets[] = javelin_tag(
'div',
array(
'class' => 'widgets-body',
@@ -101,11 +91,8 @@
'sigil' => 'widgets-files',
'style' => 'display: none;',
),
- id(new ConpherenceFileWidgetView())
- ->setUser($user)
- ->setConpherence($conpherence)
- ->setUpdateURI($this->getWidgetURI()));
- $widgets[] = phutil_tag(
+ $this->renderFileWidgetPaneContent());
+ $widgets[] = phutil_tag(
'div',
array(
'class' => 'widgets-body',
@@ -127,11 +114,25 @@
return array('widgets' => phutil_implode_html('', $widgets));
}
+ private function renderPeopleWidgetPaneContent() {
+ return id(new ConpherencePeopleWidgetView())
+ ->setUser($this->getViewer())
+ ->setConpherence($this->getConpherence())
+ ->setUpdateURI($this->getWidgetURI());
+ }
+
+ private function renderFileWidgetPaneContent() {
+ return id(new ConpherenceFileWidgetView())
+ ->setUser($this->getViewer())
+ ->setConpherence($this->getConpherence())
+ ->setUpdateURI($this->getWidgetURI());
+ }
+
private function renderSettingsWidgetPaneContent() {
- $user = $this->getRequest()->getUser();
+ $viewer = $this->getViewer();
$conpherence = $this->getConpherence();
$participants = $conpherence->getParticipants();
- $participant = $participants[$user->getPHID()];
+ $participant = $participants[$viewer->getPHID()];
$default = ConpherenceSettings::EMAIL_ALWAYS;
$preference = $this->getUserPreferences();
if ($preference) {
@@ -177,7 +178,7 @@
);
return phabricator_form(
- $user,
+ $viewer,
array(
'method' => 'POST',
'action' => $this->getWidgetURI(),
diff --git a/src/applications/conpherence/view/ConpherenceDurableColumnView.php b/src/applications/conpherence/view/ConpherenceDurableColumnView.php
--- a/src/applications/conpherence/view/ConpherenceDurableColumnView.php
+++ b/src/applications/conpherence/view/ConpherenceDurableColumnView.php
@@ -2,45 +2,76 @@
final class ConpherenceDurableColumnView extends AphrontTagView {
+ private $conpherences;
+ private $selectedConpherence;
+ private $transactions;
+
+ public function setConpherences(array $conpherences) {
+ assert_instances_of($conpherences, 'ConpherenceThread');
+ $this->conpherences = $conpherences;
+ return $this;
+ }
+
+ public function getConpherences() {
+ return $this->conpherences;
+ }
+
+ 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;
+ }
+
protected function getTagAttributes() {
return array(
- 'id' => 'durable-column',
+ 'id' => 'conpherence-durable-column',
'class' => 'conpherence-durable-column',
+ 'style' => 'display: none;',
+ 'sigil' => 'conpherence-durable-column',
);
}
protected function getTagContent() {
- Javelin::initBehavior('durable-column');
-
$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),
),
- phutil_tag(
- 'div',
- array(
- 'class' => 'conpherence-durable-column-header-text',
- ),
- pht('Column Prototype')));
-
+ $this->buildHeader());
$icon_bar = phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-icon-bar',
),
- null); // <-- TODO: Icon buttons go here.
+ $this->buildIconBar());
- $copy = pht(
- 'This is a very early prototype of a persistent column. It is not '.
- 'expected to work yet, and leaving it open will activate other new '.
- 'features which will break things. Press "\\" (backslash) on your '.
- 'keyboard to close it now.');
+ $transactions = $this->buildTransactions();
$content = phutil_tag(
'div',
@@ -53,19 +84,15 @@
'id' => 'conpherence-durable-column-content',
'class' => 'conpherence-durable-column-frame',
),
- phutil_tag(
+ javelin_tag(
'div',
array(
- 'class' => 'conpherence-durable-column-content',
+ 'class' => 'conpherence-durable-column-transactions',
+ 'sigil' => 'conpherence-durable-column-transactions',
),
- $copy)));
+ $transactions)));
- $input = phutil_tag(
- 'textarea',
- array(
- 'class' => 'conpherence-durable-column-textarea',
- 'placeholder' => pht('Box for text...'),
- ));
+ $input = $this->buildTextInput();
$footer = phutil_tag(
'div',
@@ -73,26 +100,23 @@
'class' => 'conpherence-durable-column-footer',
),
array(
- phutil_tag(
- 'button',
- array(
- 'class' => 'grey',
- ),
- pht('Send')),
+ $this->buildSendButton(),
phutil_tag(
'div',
array(
'class' => 'conpherence-durable-column-status',
),
- pht('Status Text')),
+ $this->buildStatusText()),
));
return array(
+ $loading_mask,
$header,
- phutil_tag(
+ javelin_tag(
'div',
array(
'class' => 'conpherence-durable-column-body',
+ 'sigil' => 'conpherence-durable-column-body',
),
array(
$icon_bar,
@@ -103,4 +127,161 @@
);
}
+ private function buildIconBar() {
+ return null;
+ }
+
+ private function buildHeader() {
+ $conpherence = $this->getSelectedConpherence();
+
+ if (!$conpherence) {
+
+ $title = pht('Loading...');
+ $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();
+ $cw_registry =
+ ConpherenceWidgetConfigConstants::getWidgetRegistry();
+ $first = true;
+ foreach ($cw_registry as $widget => $config) {
+ $settings_list->addMenuItem(
+ id(new PHUIListItemView())
+ ->setHref('#')
+ ->setDisabled($first)
+ ->setName($config['name'])
+ ->setIcon($config['icon'])
+ ->addSigil('conpherence-durable-column-widget-selected')
+ ->setMetadata(array(
+ 'widget' => $widget,
+ )));
+ $first = false;
+ }
+
+ $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)
+ ->setAural(pht('Settings'))
+ ->setOrder(300);
+ $settings_button = id(new PHUIListView())
+ ->addMenuItem($item)
+ ->addClass('phabricator-dark-menu')
+ ->addClass('phabricator-application-menu');
+
+ $title = $conpherence->getTitle();
+ if (!$title) {
+ $title = pht('[No Title]');
+ }
+ }
+
+ return
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'conpherence-durable-column-header',
+ ),
+ array(
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'conpherence-durable-column-header-text',
+ ),
+ $title),
+ $settings_button,
+ $settings_menu,));
+
+ }
+
+ private function buildTransactions() {
+ $conpherence = $this->getSelectedConpherence();
+ if (!$conpherence) {
+ return pht('Loading...');
+ }
+
+ $data = ConpherenceTransactionView::renderTransactions(
+ $this->getUser(),
+ $conpherence,
+ $full_display = false);
+ $messages = ConpherenceTransactionView::renderMessagePaneContent(
+ $data['transactions'],
+ $data['oldest_transaction_id']);
+
+ return $messages;
+ }
+
+ private function buildTextInput() {
+ $conpherence = $this->getSelectedConpherence();
+ $textarea = javelin_tag(
+ 'textarea',
+ array(
+ 'name' => 'text',
+ 'class' => 'conpherence-durable-column-textarea',
+ 'sigil' => 'conpherence-durable-column-textarea',
+ 'placeholder' => pht('Send a message...'),
+ ));
+ if (!$conpherence) {
+ return $textarea;
+ }
+
+ $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() {
+ return javelin_tag(
+ 'button',
+ array(
+ 'class' => 'grey',
+ 'sigil' => 'conpherence-send-message',
+ ),
+ pht('Send'));
+ }
+
}
diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php
--- a/src/applications/conpherence/view/ConpherenceLayoutView.php
+++ b/src/applications/conpherence/view/ConpherenceLayoutView.php
@@ -79,52 +79,7 @@
$this->initBehavior(
'conpherence-widget-pane',
- array(
- 'widgetBaseUpdateURI' => $this->baseURI.'update/',
- 'widgetRegistry' => array(
- 'conpherence-message-pane' => array(
- 'name' => pht('Thread'),
- 'icon' => 'fa-comment',
- 'deviceOnly' => true,
- 'hasCreate' => false,
- ),
- 'widgets-people' => array(
- 'name' => pht('Participants'),
- 'icon' => 'fa-users',
- 'deviceOnly' => false,
- 'hasCreate' => true,
- 'createData' => array(
- 'refreshFromResponse' => true,
- 'action' => ConpherenceUpdateActions::ADD_PERSON,
- 'customHref' => null,
- ),
- ),
- 'widgets-files' => array(
- 'name' => pht('Files'),
- 'icon' => 'fa-files-o',
- 'deviceOnly' => false,
- 'hasCreate' => false,
- ),
- 'widgets-calendar' => array(
- 'name' => pht('Calendar'),
- 'icon' => 'fa-calendar',
- 'deviceOnly' => false,
- 'hasCreate' => true,
- 'createData' => array(
- 'refreshFromResponse' => false,
- 'action' => ConpherenceUpdateActions::ADD_STATUS,
- 'customHref' => '/calendar/event/create/',
- ),
- ),
- 'widgets-settings' => array(
- 'name' => pht('Settings'),
- 'icon' => 'fa-wrench',
- 'deviceOnly' => false,
- 'hasCreate' => false,
- ),
- ),
- ));
-
+ ConpherenceWidgetConfigConstants::getWidgetPaneBehaviorConfig());
return javelin_tag(
'div',
diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php
--- a/src/applications/conpherence/view/ConpherenceTransactionView.php
+++ b/src/applications/conpherence/view/ConpherenceTransactionView.php
@@ -5,6 +5,8 @@
private $conpherenceTransaction;
private $handles;
private $markupEngine;
+ private $showImages = true;
+ private $showContentSource = true;
public function setMarkupEngine(PhabricatorMarkupEngine $markup_engine) {
$this->markupEngine = $markup_engine;
@@ -30,6 +32,24 @@
return $this->conpherenceTransaction;
}
+ public function setShowImages($bool) {
+ $this->showImages = $bool;
+ return $this;
+ }
+
+ private function getShowImages() {
+ return $this->showImages;
+ }
+
+ public function setShowContentSource($bool) {
+ $this->showContentSource = $bool;
+ return $this;
+ }
+
+ private function getShowContentSource() {
+ return $this->showContentSource;
+ }
+
public function render() {
$user = $this->getUser();
$transaction = $this->getConpherenceTransaction();
@@ -59,8 +79,10 @@
$author = $handles[$transaction->getAuthorPHID()];
$transaction_view = id(new PhabricatorTransactionView())
->setUser($user)
- ->setEpoch($transaction->getDateCreated())
- ->setContentSource($transaction->getContentSource());
+ ->setEpoch($transaction->getDateCreated());
+ if ($this->getShowContentSource()) {
+ $transaction_view->setContentSource($transaction->getContentSource());
+ }
$content = null;
$content_class = null;
@@ -83,9 +105,10 @@
$comment,
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
$content_class = 'conpherence-message phabricator-remarkup';
- $transaction_view
- ->setImageURI($author->getImageURI())
- ->setActions(array($author->renderLink()));
+ if ($this->getShowImages()) {
+ $transaction_view->setImageURI($author->getImageURI());
+ }
+ $transaction_view->setActions(array($author->renderLink()));
break;
}
@@ -100,4 +123,108 @@
return $transaction_view->render();
}
+ public static function renderTransactions(
+ PhabricatorUser $user,
+ ConpherenceThread $conpherence,
+ $full_display = true) {
+
+ $transactions = $conpherence->getTransactions();
+ $oldest_transaction_id = 0;
+ $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1;
+ if (count($transactions) == $too_many) {
+ $last_transaction = end($transactions);
+ unset($transactions[$last_transaction->getID()]);
+ $oldest_transaction = end($transactions);
+ $oldest_transaction_id = $oldest_transaction->getID();
+ }
+ $transactions = array_reverse($transactions);
+ $handles = $conpherence->getHandles();
+ $rendered_transactions = array();
+ $engine = id(new PhabricatorMarkupEngine())
+ ->setViewer($user);
+ foreach ($transactions as $key => $transaction) {
+ if ($transaction->shouldHide()) {
+ unset($transactions[$key]);
+ continue;
+ }
+ if ($transaction->getComment()) {
+ $engine->addObject(
+ $transaction->getComment(),
+ PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
+ }
+ }
+ $engine->process();
+ // we're going to insert a dummy date marker transaction for breaks
+ // between days. some setup required!
+ $previous_transaction = null;
+ $date_marker_transaction = id(new ConpherenceTransaction())
+ ->setTransactionType(ConpherenceTransactionType::TYPE_DATE_MARKER)
+ ->makeEphemeral();
+ $date_marker_transaction_view = id(new ConpherenceTransactionView())
+ ->setUser($user)
+ ->setConpherenceTransaction($date_marker_transaction)
+ ->setHandles($handles)
+ ->setShowImages($full_display)
+ ->setShowContentSource($full_display)
+ ->setMarkupEngine($engine);
+ foreach ($transactions as $transaction) {
+ if ($previous_transaction) {
+ $previous_day = phabricator_format_local_time(
+ $previous_transaction->getDateCreated(),
+ $user,
+ 'Ymd');
+ $current_day = phabricator_format_local_time(
+ $transaction->getDateCreated(),
+ $user,
+ 'Ymd');
+ // date marker transaction time!
+ if ($previous_day != $current_day) {
+ $date_marker_transaction->setDateCreated(
+ $transaction->getDateCreated());
+ $rendered_transactions[] = $date_marker_transaction_view->render();
+ }
+ }
+ $rendered_transactions[] = id(new ConpherenceTransactionView())
+ ->setUser($user)
+ ->setConpherenceTransaction($transaction)
+ ->setHandles($handles)
+ ->setMarkupEngine($engine)
+ ->setShowImages($full_display)
+ ->setShowContentSource($full_display)
+ ->render();
+ $previous_transaction = $transaction;
+ }
+ $latest_transaction_id = $transaction->getID();
+
+ return array(
+ 'transactions' => $rendered_transactions,
+ 'latest_transaction' => $transaction,
+ 'latest_transaction_id' => $latest_transaction_id,
+ 'oldest_transaction_id' => $oldest_transaction_id,
+ );
+ }
+
+ public static function renderMessagePaneContent(
+ array $transactions,
+ $oldest_transaction_id) {
+
+ $scrollbutton = '';
+ if ($oldest_transaction_id) {
+ $scrollbutton = javelin_tag(
+ 'a',
+ array(
+ 'href' => '#',
+ 'mustcapture' => true,
+ 'sigil' => 'show-older-messages',
+ 'class' => 'conpherence-show-older-messages',
+ 'meta' => array(
+ 'oldest_transaction_id' => $oldest_transaction_id,
+ ),
+ ),
+ pht('Show Older Messages'));
+ }
+
+ return hsprintf('%s%s', $scrollbutton, $transactions);
+ }
+
}
diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php
--- a/src/view/page/PhabricatorStandardPageView.php
+++ b/src/view/page/PhabricatorStandardPageView.php
@@ -80,7 +80,14 @@
}
public function getShowDurableColumn() {
- return $this->showDurableColumn;
+ $request = $this->getRequest();
+ if ($request) {
+ $viewer = $request->getUser();
+ return PhabricatorApplication::isClassInstalledForViewer(
+ 'PhabricatorConpherenceApplication',
+ $viewer);
+ }
+ return false;
}
public function getTitle() {
@@ -391,7 +398,12 @@
$durable_column = null;
if ($this->getShowDurableColumn()) {
- $durable_column = new ConpherenceDurableColumnView();
+ $durable_column = id(new ConpherenceDurableColumnView())
+ ->setSelectedConpherence(null)
+ ->setUser($user);
+ Javelin::initBehavior(
+ 'durable-column',
+ array());
}
return phutil_tag(
diff --git a/webroot/rsrc/css/application/conpherence/durable-column.css b/webroot/rsrc/css/application/conpherence/durable-column.css
--- a/webroot/rsrc/css/application/conpherence/durable-column.css
+++ b/webroot/rsrc/css/application/conpherence/durable-column.css
@@ -13,7 +13,22 @@
right: 0;
width: 300px;
background: #fff;
+}
+
+.conpherence-durable-column .loading-mask {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ width: 300px;
+ background: #fff;
display: none;
+ opacity: .6;
+ z-index: 2;
+}
+
+.conpherence-durable-column.loading .loading-mask {
+ display: block;
}
.conpherence-durable-column-header {
@@ -21,10 +36,16 @@
border-left: 1px solid #000;
}
+.conpherence-durable-column-header .conpherence-settings-dropdown {
+ z-index: 1;
+}
+
.conpherence-durable-column-header-text {
+ float: left;
padding: 12px 16px;
font-size: 15px;
color: rgba(255,255,255,.8);
+ width: 230px;
}
.conpherence-durable-column-header-text:hover {
@@ -55,10 +76,36 @@
overflow: hidden;
}
-.conpherence-durable-column-content {
+.conpherence-durable-column-transactions {
padding: 8px 12px;
}
+.conpherence-durable-column-transactions .phabricator-transaction-view {
+ background: none;
+ margin: 0 10px 0 0;
+ padding: 0;
+}
+
+.conpherence-durable-column-transactions .phabricator-transaction-detail {
+ border: 0;
+ margin: 0;
+}
+
+.conpherence-durable-column-transactions .phabricator-transaction-detail
+.phabricator-transaction-header {
+ background: none;
+ padding: 0;
+}
+.conpherence-durable-column-transactions .phabricator-transaction-detail
+.phabricator-transaction-header .phabricator-transaction-info {
+ margin: 3px 0px 0px 0px;
+}
+
+.conpherence-durable-column-transactions .phabricator-transaction-detail
+.phabricator-transaction-content {
+ padding: 0;
+}
+
.conpherence-durable-column-textarea {
position: absolute;
left: 0;
@@ -82,6 +129,239 @@
box-shadow: none;
}
+/* participants widget */
+
+.conpherence-durable-column-body .person-entry {
+ padding: 8px 0 0 8px;
+}
+
+.conpherence-durable-column-body .person-entry a {
+ float: left;
+ font-weight: bold;
+ line-height: 20px;
+}
+
+.conpherence-durable-column-body .person-entry a img {
+ height: 35px;
+ width: 35px;
+}
+
+.conpherence-durable-column-body .person-entry .pic {
+ float: left;
+ margin: 0 8px 0 0;
+ width: 35px;
+ padding: 0;
+}
+
+.conpherence-durable-column-body .person-entry .remove {
+ float: right;
+ width: 20px;
+ font-size: 18px;
+ padding: 5px 0 8px 0;
+}
+
+.conpherence-durable-column-body .person-entry .remove:hover {
+ text-decoration: none;
+}
+
+.conpherence-durable-column-body .person-entry .remove .close-icon {
+ color: #bfbfbf;
+}
+
+.conpherence-durable-column-body .person-entry .remove:hover .close-icon {
+ color: #000;
+}
+
+/* files widget */
+
+.conpherence-durable-column-body .no-files {
+ width: 100%;
+ padding: 20px 0px;
+ text-align: center;
+ color: #555;
+}
+
+.conpherence-durable-column-body .file-entry {
+ padding: 10px 0;
+ margin: 0 5px 0 10px;
+ border-bottom: 1px solid #e7e7e7;
+}
+.conpherence-durable-column-body .file-icon {
+ width: 32px;
+ height: 32px;
+ float: left;
+ font-size: 30px;
+}
+.conpherence-durable-column-body .file-title {
+ display: block;
+ position: relative;
+ top: -4px;
+ left: 2px;
+ overflow-x: hidden;
+ width: 180px;
+ font-weight: bold;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.conpherence-durable-column-body .file-uploaded-by {
+ color: #a1a5a9;
+ position: relative;
+ top: 0px;
+ left: 2px;
+ width: 170px;
+ font-size: 11px;
+}
+
+/* calendar widget */
+
+.conpherence-durable-column-body .aphront-multi-column-view {
+ width: 100%;
+}
+
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column {
+ background: white;
+ border-right: 1px solid #bfbfbf;
+ text-align: center;
+}
+
+.conpherence-durable-column-body .no-events {
+ color: {$lightgreytext};
+}
+
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column-last {
+ border-right: 0;
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .day-column,
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .day-column-active {
+ color: #bfbfbf;
+ background-color: white;
+ font-weight: bold;
+ padding: 0px 0px 10px 0px;
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .day-column-active {
+ color: black;
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .present ,
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .sporadic ,
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .away {
+ height: 10px;
+ margin: 5px 0px 5px 0px;
+ width: 100%;
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .present {
+ background-color: white;
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .sporadic {
+ background-color: rgb(222, 226, 232);
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+.aphront-multi-column-column .away {
+ background-color: rgb(102, 204, 255);
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+ .day-name {
+ padding: 5px 0px 0px 0px;
+ font-size: 12px;
+}
+.conpherence-durable-column-body .aphront-multi-column-view
+ .day-number {
+ font-size: 16px;
+ padding: 0 0 5px 0;
+}
+
+.conpherence-durable-column-body .day-header {
+ overflow: hidden;
+ background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
+ background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
+ border-top: 1px solid #e7e7e7;
+ border-bottom: 1px solid #d7d7d7;
+ padding: 5px 10px 5px 10px;
+}
+
+.conpherence-durable-column-body .day-header.today {
+ background-image: linear-gradient(to bottom, #3b86c4, #2b628f);
+ background-image: -webkit-linear-gradient(top, #3b86c4, #2b628f);
+ border-top: none;
+ border-bottom: none;
+}
+
+.conpherence-durable-column-body .day-header.today .day-name,
+.conpherence-durable-column-body .day-header.today .day-date {
+ color: #fff;
+}
+
+.conpherence-durable-column-body .day-header .day-name {
+ float: left;
+ color: #555759;
+ font-weight: bold;
+ text-transform: uppercase;
+ font-size: 11px;
+}
+
+.conpherence-durable-column-body .day-header .day-date {
+ float: right;
+ color: #555759;
+ font-size: 11px;
+}
+
+.conpherence-durable-column-body .top-border {
+ border-top: 1px solid #E7E7E7;
+}
+
+.conpherence-durable-column-body .user-status {
+ padding: 10px 0px 10px 0px;
+ margin: 0px 0px 0px 10px;
+}
+
+.conpherence-durable-column-body .user-status .icon {
+ border-radius: 8px;
+ height: 14px;
+ width: 14px;
+ margin-top: 7px;
+ float: left;
+}
+
+.conpherence-durable-column-body .sporadic .icon {
+ background-color: rgb(222, 226, 232);
+}
+
+.conpherence-durable-column-body .away .icon {
+ background-color: rgb(102, 204, 255);
+}
+
+.conpherence-durable-column-body .user-status .description {
+ width: 195px;
+ text-overflow: ellipsis;
+ margin: 0 0 0px 20px;
+}
+
+.conpherence-durable-column-body .user-status .participant {
+ font-size: 11px;
+ color: {$lightgreytext};
+ padding-top: 2px;
+}
+
+/* settings widget */
+
+.conpherence-durable-column-body .notifications-update {
+ margin: 0px 12px;
+}
+
+.conpherence-durable-column-body .aphront-form-input {
+ margin: 8px 12px;
+ width: 100%;
+}
+
.conpherence-durable-column-footer {
position: absolute;
height: 26px;
diff --git a/webroot/rsrc/css/core/z-index.css b/webroot/rsrc/css/core/z-index.css
--- a/webroot/rsrc/css/core/z-index.css
+++ b/webroot/rsrc/css/core/z-index.css
@@ -75,6 +75,7 @@
z-index: 5;
}
+.conpherence-durable-column-header,
.phabricator-main-menu {
z-index: 6;
}
diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
--- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
+++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
@@ -148,7 +148,11 @@
JX.DOM.show(dropdown);
p.y = null;
- if (config.right) {
+ if (config.containerDivID) {
+ var pc = JX.$V(JX.$(config.containerDivID));
+ p.x -= (JX.Vector.getDim(dropdown).x - JX.Vector.getDim(bubble).x +
+ pc.x);
+ } else if (config.right) {
p.x -= (JX.Vector.getDim(dropdown).x - JX.Vector.getDim(bubble).x);
} else {
p.x -= 6;
diff --git a/webroot/rsrc/js/application/conpherence/behavior-durable-column.js b/webroot/rsrc/js/application/conpherence/behavior-durable-column.js
--- a/webroot/rsrc/js/application/conpherence/behavior-durable-column.js
+++ b/webroot/rsrc/js/application/conpherence/behavior-durable-column.js
@@ -6,19 +6,113 @@
* javelin-scrollbar
* javelin-quicksand
* phabricator-keyboard-shortcut
+ * javelin-behavior-conpherence-widget-pane
*/
JX.behavior('durable-column', function() {
+ var shouldInit = true;
+ var loadThreadID = null;
+ var loadedThreadID = null;
+ var loadedThreadPHID = null;
+ var latestTransactionID = null;
+
var frame = JX.$('phabricator-standard-page');
var quick = JX.$('phabricator-standard-page-body');
var show = false;
- new JX.KeyboardShortcut('\\', 'Toggle Column (Prototype)')
+
+ // TODO - this "upating" stuff is a copy from behavior-pontificate
+ // TODO: This isn't very clean. When you submit a message, you may get a
+ // notification about it back before you get the rendered message back. To
+ // prevent this, we keep track of whether we're currently updating the
+ // thread. If we are, we hold further updates until the response comes
+ // back.
+
+ // After the response returns, we'll do another update if we know about
+ // a transaction newer than the one we got back from the server.
+ var updating = null;
+ // Copy continues with slight modifications for how we store data now
+ JX.Stratcom.listen('aphlict-server-message', null, function(e) {
+ var message = e.getData();
+
+ if (message.type != 'message') {
+ // Not a message event.
+ return;
+ }
+
+ if (message.threadPHID != loadedThreadPHID) {
+ // Message event for some thread other than the visible one.
+ return;
+ }
+
+ if (message.messageID <= latestTransactionID) {
+ // Message event for something we already know about.
+ return;
+ }
+
+ // If we're currently updating, wait for the update to complete.
+ // If this notification tells us about a message which is newer than the
+ // newest one we know to exist, keep track of it so we can update once
+ // the in-flight update finishes.
+ if (updating && updating.threadPHID == loadedThreadPHID) {
+ if (message.messageID > updating.knownID) {
+ updating.knownID = message.messageID;
+ return;
+ }
+ }
+
+ update_thread();
+ });
+ function update_thread() {
+ var params = {
+ action: 'load',
+ latest_transaction_id: latestTransactionID,
+ minimal_display: true
+ };
+
+ var uri = '/conpherence/update/' + loadedThreadID + '/';
+
+ var workflow = new JX.Workflow(uri)
+ .setData(params)
+ .setHandler(function(r) {
+ var messages = _getColumnMessagesNode();
+ JX.DOM.appendContent(messages, JX.$H(r.transactions));
+ messages.scrollTop = messages.scrollHeight;
+
+ latestTransactionID = r.latest_transaction_id;
+ });
+
+ sync_workflow(workflow);
+ }
+ function sync_workflow(workflow) {
+ updating = {
+ threadPHID: loadedThreadPHID,
+ knownID: latestTransactionID
+ };
+ workflow.listen('finally', function() {
+ var need_sync = (updating.knownID > latestTransactionID);
+ updating = null;
+ if (need_sync) {
+ update_thread();
+ }
+ });
+ workflow.start();
+ }
+ // end copy / hack of stuff with big ole TODO on it
+
+
+ new JX.KeyboardShortcut('\\', 'Toggle Conpherence Column')
.setHandler(function() {
show = !show;
JX.DOM.alterClass(frame, 'with-durable-column', show);
- JX.$('durable-column').style.display = (show ? 'block' : 'none');
+ var column = JX.$('conpherence-durable-column');
+ if (show) {
+ JX.DOM.show(column);
+ loadThreadContent(loadThreadID);
+ } else {
+ JX.DOM.hide(column);
+ }
JX.Stratcom.invoke('resize');
JX.Quicksand.setFrame(show ? quick : null);
})
@@ -28,4 +122,149 @@
JX.Quicksand.start();
+ JX.Stratcom.listen(
+ 'click',
+ 'conpherence-durable-column-widget-selected',
+ function (e) {
+ e.kill();
+ var data = e.getNodeData('conpherence-durable-column-widget-selected');
+ var widget = data.widget;
+ if (widget == 'conpherence-message-pane') {
+ return loadThreadContent(loadThreadID);
+ }
+
+ _markLoading(true);
+ var uri = '/conpherence/widget/' + loadThreadID + '/';
+ loadedThreadID = null;
+
+ var params = { widget : widget };
+ new JX.Workflow(uri)
+ .setData(params)
+ .setHandler(function(r) {
+ var body = _getColumnBodyNode();
+ JX.DOM.setContent(body, JX.$H(r));
+ new JX.Scrollbar(JX.$('conpherence-durable-column-content'));
+ _markLoading(false);
+ })
+ .start();
+ });
+
+ function _getColumnNode() {
+ return JX.$('conpherence-durable-column');
+ }
+
+ function _getColumnBodyNode() {
+ var column = JX.$('conpherence-durable-column');
+ return JX.DOM.find(
+ column,
+ 'div',
+ 'conpherence-durable-column-body');
+ }
+
+ function _getColumnMessagesNode() {
+ var column = JX.$('conpherence-durable-column');
+ return JX.DOM.find(
+ column,
+ 'div',
+ 'conpherence-durable-column-transactions');
+ }
+
+ function _getColumnFormNode() {
+ var column = JX.$('conpherence-durable-column');
+ return JX.DOM.find(
+ column,
+ 'form',
+ 'conpherence-message-form');
+ }
+
+ function _getColumnTextareaNode() {
+ var column = JX.$('conpherence-durable-column');
+ return JX.DOM.find(
+ column,
+ 'textarea',
+ 'conpherence-durable-column-textarea');
+ }
+
+ function _focusColumnTextareaNode() {
+ var textarea = _getColumnTextareaNode();
+ setTimeout(function() { JX.DOM.focus(textarea); }, 1);
+ }
+
+ function _markLoading(loading) {
+ var column = _getColumnNode();
+ JX.DOM.alterClass(column, 'loading', loading);
+ }
+
+ function loadThreadContent(thread_id) {
+ // loaded this thread already
+ if (loadedThreadID !== null && loadedThreadID == thread_id) {
+ return;
+ }
+ _markLoading(true);
+
+ var uri = '/conpherence/columnview/';
+ var params = null;
+ // We can pick a thread from the server the first time
+ if (shouldInit) {
+ shouldInit = false;
+ params = { shouldInit : true };
+ } else {
+ params = { id : thread_id };
+ }
+ var handler = function(r) {
+ var column = _getColumnNode();
+ var new_column = JX.$H(r.content);
+ loadedThreadID = r.threadID;
+ loadedThreadPHID = r.threadPHID;
+ loadThreadID = r.threadID;
+ latestTransactionID = r.latestTransactionID;
+ JX.DOM.replace(column, new_column);
+ JX.DOM.show(_getColumnNode());
+ new JX.Scrollbar(JX.$('conpherence-durable-column-content'));
+ _markLoading(false);
+ };
+
+ new JX.Workflow(uri)
+ .setData(params)
+ .setHandler(handler)
+ .start();
+ }
+
+ function _sendMessage(e) {
+ e.kill();
+ _markLoading(true);
+
+ var form = _getColumnFormNode();
+ var params = {
+ latest_transaction_id : latestTransactionID,
+ minimal_display : true
+ };
+ var workflow = JX.Workflow.newFromForm(form, params)
+ .setHandler(function(r) {
+ var messages = _getColumnMessagesNode();
+ JX.DOM.appendContent(messages, JX.$H(r.transactions));
+ messages.scrollTop = messages.scrollHeight;
+
+ var textarea = _getColumnTextareaNode();
+ textarea.value = '';
+
+ latestTransactionID = r.latest_transaction_id;
+
+ _markLoading(false);
+
+ _focusColumnTextareaNode();
+ });
+ sync_workflow(workflow);
+ }
+
+ JX.Stratcom.listen(
+ 'click',
+ 'conpherence-send-message',
+ _sendMessage);
+
+ JX.Stratcom.listen(
+ ['submit', 'didSyntheticSubmit'],
+ 'conpherence-message-form',
+ _sendMessage);
+
});

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 1:53 PM (1 d, 8 h ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/7a/5x/jduoavrlf2vimdqz
Default Alt Text
D11968.diff (59 KB)

Event Timeline