Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F18496670
D11968.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
59 KB
Referenced Files
None
Subscribers
None
D11968.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Fri, Sep 5, 5:36 PM (1 w, 6 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/uy/n6/uenhdji3outvdl33
Default Alt Text
D11968.diff (59 KB)
Attached To
Mode
D11968: Conpherence - make the durable column kind of work and stuff
Attached
Detach File
Event Timeline
Log In to Comment