diff --git a/resources/celerity/map.php b/resources/celerity/map.php index c3e0b80f66..92b732ed70 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,8 +7,8 @@ */ return array( 'names' => array( - 'conpherence.pkg.css' => 'fdc05791', - 'core.pkg.css' => '1ca373de', + 'conpherence.pkg.css' => '7bddd31a', + 'core.pkg.css' => 'dc6d08e3', 'core.pkg.js' => '1d376fa9', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => '3fb7f532', @@ -19,7 +19,7 @@ return array( 'maniphest.pkg.js' => '949a7498', 'rsrc/css/aphront/aphront-bars.css' => '231ac33c', 'rsrc/css/aphront/dark-console.css' => 'f54bf286', - 'rsrc/css/aphront/dialog-view.css' => '913c172e', + 'rsrc/css/aphront/dialog-view.css' => '593d3f67', 'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d', 'rsrc/css/aphront/list-filter-view.css' => '5d6f0526', 'rsrc/css/aphront/multi-column.css' => 'fd18389d', @@ -46,12 +46,13 @@ return array( 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 'rsrc/css/application/conpherence/durable-column.css' => '194ac487', + 'rsrc/css/application/conpherence/header-pane.css' => 'bdba8a5b', 'rsrc/css/application/conpherence/menu.css' => '8344d122', - 'rsrc/css/application/conpherence/message-pane.css' => 'ee0e27be', + 'rsrc/css/application/conpherence/message-pane.css' => 'c075e8fe', 'rsrc/css/application/conpherence/notification.css' => '6cdcc253', - 'rsrc/css/application/conpherence/transaction.css' => '2c71247c', - 'rsrc/css/application/conpherence/update.css' => 'faf6be09', - 'rsrc/css/application/conpherence/widget-pane.css' => 'a131d5b6', + 'rsrc/css/application/conpherence/transaction.css' => '46253e19', + 'rsrc/css/application/conpherence/update.css' => '53bc527a', + 'rsrc/css/application/conpherence/widget-pane.css' => '827a21f1', 'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4', 'rsrc/css/application/countdown/timer.css' => '16c52f5c', 'rsrc/css/application/daemon/bulk-job.css' => 'df9c1d4a', @@ -108,7 +109,7 @@ return array( 'rsrc/css/core/core.css' => 'd0801452', 'rsrc/css/core/remarkup.css' => 'cd912f2c', 'rsrc/css/core/syntax.css' => '769d3498', - 'rsrc/css/core/z-index.css' => '2b01a823', + 'rsrc/css/core/z-index.css' => 'a847e919', 'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa', 'rsrc/css/font/font-aleo.css' => '8bdb2835', 'rsrc/css/font/font-awesome.css' => '2b7ebbcc', @@ -437,11 +438,11 @@ return array( 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '01774ab2', 'rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js' => 'cf86d16a', 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'd3506890', - 'rsrc/js/application/conpherence/behavior-menu.js' => '1d45c74d', + 'rsrc/js/application/conpherence/behavior-menu.js' => '7a2f5952', + 'rsrc/js/application/conpherence/behavior-participants-pane.js' => '08872fb7', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', - 'rsrc/js/application/conpherence/behavior-toggle-widget.js' => 'b151bbbc', - 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '65845387', + 'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '9bdbbab0', 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => 'edf8a145', 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', @@ -601,7 +602,7 @@ return array( 'almanac-css' => 'dbb9b3af', 'aphront-bars' => '231ac33c', 'aphront-dark-console-css' => 'f54bf286', - 'aphront-dialog-view-css' => '913c172e', + 'aphront-dialog-view-css' => '593d3f67', 'aphront-list-filter-view-css' => '5d6f0526', 'aphront-multi-column-view-css' => 'fd18389d', 'aphront-panel-view-css' => '8427b78d', @@ -617,13 +618,14 @@ return array( 'config-options-css' => '0ede4c9b', 'config-page-css' => '8798e14f', 'conpherence-durable-column-view' => '194ac487', + 'conpherence-header-pane-css' => 'bdba8a5b', 'conpherence-menu-css' => '8344d122', - 'conpherence-message-pane-css' => 'ee0e27be', + 'conpherence-message-pane-css' => 'c075e8fe', 'conpherence-notification-css' => '6cdcc253', 'conpherence-thread-manager' => '01774ab2', - 'conpherence-transaction-css' => '2c71247c', - 'conpherence-update-css' => 'faf6be09', - 'conpherence-widget-pane-css' => 'a131d5b6', + 'conpherence-transaction-css' => '46253e19', + 'conpherence-update-css' => '53bc527a', + 'conpherence-widget-pane-css' => '827a21f1', 'd3' => 'a11a5ff2', 'differential-changeset-view-css' => '9ef7d354', 'differential-core-view-css' => '5b7b8ff4', @@ -665,9 +667,9 @@ return array( 'javelin-behavior-comment-actions' => '0300eae6', 'javelin-behavior-config-reorder-fields' => 'b6993408', 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', - 'javelin-behavior-conpherence-menu' => '1d45c74d', + 'javelin-behavior-conpherence-menu' => '7a2f5952', + 'javelin-behavior-conpherence-participants-pane' => '08872fb7', 'javelin-behavior-conpherence-pontificate' => '21ba5861', - 'javelin-behavior-conpherence-widget-pane' => '65845387', 'javelin-behavior-countdown-timer' => 'e4cc26b3', 'javelin-behavior-dark-console' => 'f411b6ae', 'javelin-behavior-dashboard-async-panel' => '469c0d9e', @@ -773,7 +775,7 @@ return array( 'javelin-behavior-test-payment-form' => 'fc91ab6c', 'javelin-behavior-time-typeahead' => '522431f7', 'javelin-behavior-toggle-class' => '92b9ec77', - 'javelin-behavior-toggle-widget' => 'b151bbbc', + 'javelin-behavior-toggle-widget' => '9bdbbab0', 'javelin-behavior-typeahead-browse' => '635de1ec', 'javelin-behavior-typeahead-search' => '93d0c9e3', 'javelin-behavior-view-placeholder' => '47830651', @@ -881,7 +883,7 @@ return array( 'phabricator-uiexample-reactor-select' => 'a155550f', 'phabricator-uiexample-reactor-sendclass' => '1def2711', 'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee', - 'phabricator-zindex-css' => '2b01a823', + 'phabricator-zindex-css' => 'a847e919', 'phame-css' => '8efb0729', 'pholio-css' => 'ca89d380', 'pholio-edit-css' => '07676f51', @@ -1057,6 +1059,15 @@ return array( 'javelin-stratcom', 'javelin-vector', ), + '08872fb7' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-util', + 'phabricator-notification', + 'conpherence-thread-manager', + ), '0a0b10e9' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1135,20 +1146,6 @@ return array( 'javelin-request', 'javelin-uri', ), - '1d45c74d' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-behavior-device', - 'javelin-history', - 'javelin-vector', - 'javelin-scrollbar', - 'phabricator-title', - 'phabricator-shaped-request', - 'conpherence-thread-manager', - ), '1def2711' => array( 'javelin-install', 'javelin-dom', @@ -1484,19 +1481,6 @@ return array( 'javelin-request', 'javelin-workflow', ), - 65845387 => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-util', - 'phabricator-notification', - 'javelin-behavior-device', - 'phuix-dropdown-menu', - 'phuix-action-list-view', - 'phuix-action-view', - 'conpherence-thread-manager', - ), '680ea2c8' => array( 'javelin-install', 'javelin-dom', @@ -1587,6 +1571,20 @@ return array( 'javelin-behavior', 'javelin-quicksand', ), + '7a2f5952' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-behavior-device', + 'javelin-history', + 'javelin-vector', + 'javelin-scrollbar', + 'phabricator-title', + 'phabricator-shaped-request', + 'conpherence-thread-manager', + ), '7a68dda3' => array( 'owners-path-editor', 'javelin-behavior', @@ -1755,6 +1753,13 @@ return array( 'phabricator-phtize', 'changeset-view-manager', ), + '9bdbbab0' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'javelin-workflow', + 'javelin-stratcom', + ), '9ef7d354' => array( 'phui-inline-comment-view-css', ), @@ -1850,13 +1855,6 @@ return array( 'javelin-util', 'phabricator-shaped-request', ), - 'b151bbbc' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-workflow', - 'javelin-stratcom', - ), 'b1f0ccee' => array( 'javelin-install', 'javelin-dom', @@ -2311,6 +2309,7 @@ return array( 'conpherence-transaction-css', 'conpherence-update-css', 'conpherence-widget-pane-css', + 'conpherence-header-pane-css', ), 'core.pkg.css' => array( 'phabricator-core-css', diff --git a/resources/celerity/packages.php b/resources/celerity/packages.php index 0270b70b86..e40277d0a5 100644 --- a/resources/celerity/packages.php +++ b/resources/celerity/packages.php @@ -159,6 +159,7 @@ return array( 'conpherence-transaction-css', 'conpherence-update-css', 'conpherence-widget-pane-css', + 'conpherence-header-pane-css', ), 'differential.pkg.css' => array( 'differential-core-view-css', diff --git a/resources/sql/autopatches/20160913.conpherence.topic.1.sql b/resources/sql/autopatches/20160913.conpherence.topic.1.sql new file mode 100644 index 0000000000..186a5b5c58 --- /dev/null +++ b/resources/sql/autopatches/20160913.conpherence.topic.1.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread + ADD topic VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT}; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index bbd0bbab2b..49a296b8a6 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -300,10 +300,11 @@ phutil_register_library_map(array( 'ConpherenceNewRoomController' => 'applications/conpherence/controller/ConpherenceNewRoomController.php', 'ConpherenceNotificationPanelController' => 'applications/conpherence/controller/ConpherenceNotificationPanelController.php', 'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php', + 'ConpherenceParticipantController' => 'applications/conpherence/controller/ConpherenceParticipantController.php', 'ConpherenceParticipantCountQuery' => 'applications/conpherence/query/ConpherenceParticipantCountQuery.php', 'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php', + 'ConpherenceParticipantView' => 'applications/conpherence/view/ConpherenceParticipantView.php', 'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php', - 'ConpherencePeopleWidgetView' => 'applications/conpherence/view/ConpherencePeopleWidgetView.php', 'ConpherencePicCropControl' => 'applications/conpherence/view/ConpherencePicCropControl.php', 'ConpherenceQueryThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php', 'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php', @@ -329,9 +330,6 @@ phutil_register_library_map(array( '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', 'DarkConsoleCore' => 'applications/console/core/DarkConsoleCore.php', 'DarkConsoleDataController' => 'applications/console/controller/DarkConsoleDataController.php', @@ -4768,10 +4766,11 @@ phutil_register_library_map(array( 'ConpherenceNewRoomController' => 'ConpherenceController', 'ConpherenceNotificationPanelController' => 'ConpherenceController', 'ConpherenceParticipant' => 'ConpherenceDAO', + 'ConpherenceParticipantController' => 'ConpherenceController', 'ConpherenceParticipantCountQuery' => 'PhabricatorOffsetPagedQuery', 'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery', + 'ConpherenceParticipantView' => 'AphrontView', 'ConpherenceParticipationStatus' => 'ConpherenceConstants', - 'ConpherencePeopleWidgetView' => 'ConpherenceWidgetView', 'ConpherencePicCropControl' => 'AphrontFormControl', 'ConpherenceQueryThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod', @@ -4803,9 +4802,6 @@ phutil_register_library_map(array( 'ConpherenceUpdateController' => 'ConpherenceController', 'ConpherenceUpdateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceViewController' => 'ConpherenceController', - 'ConpherenceWidgetConfigConstants' => 'ConpherenceConstants', - 'ConpherenceWidgetController' => 'ConpherenceController', - 'ConpherenceWidgetView' => 'AphrontView', 'DarkConsoleController' => 'PhabricatorController', 'DarkConsoleCore' => 'Phobject', 'DarkConsoleDataController' => 'PhabricatorController', diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php index 8defc4d2be..4bc4ab70e1 100644 --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -42,7 +42,7 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication { 'search/(?:query/(?P[^/]+)/)?' => 'ConpherenceRoomListController', 'panel/' => 'ConpherenceNotificationPanelController', - 'widget/(?P[1-9]\d*)/' => 'ConpherenceWidgetController', + 'participant/(?P[1-9]\d*)/' => 'ConpherenceParticipantController', 'update/(?P[1-9]\d*)/' => 'ConpherenceUpdateController', ), ); diff --git a/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php index 30540bf242..85f450a648 100644 --- a/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php +++ b/src/applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php @@ -13,8 +13,9 @@ final class ConpherenceCreateThreadConduitAPIMethod protected function defineParamTypes() { return array( - 'title' => 'optional string', - 'message' => 'required string', + 'title' => 'required string', + 'topic' => 'optional string', + 'message' => 'optional string', 'participantPHIDs' => 'required list', ); } @@ -27,8 +28,8 @@ final class ConpherenceCreateThreadConduitAPIMethod return array( 'ERR_EMPTY_PARTICIPANT_PHIDS' => pht( 'You must specify participant phids.'), - 'ERR_EMPTY_MESSAGE' => pht( - 'You must specify a message.'), + 'ERR_EMPTY_TITLE' => pht( + 'You must specify a title.'), ); } @@ -36,19 +37,21 @@ final class ConpherenceCreateThreadConduitAPIMethod $participant_phids = $request->getValue('participantPHIDs', array()); $message = $request->getValue('message'); $title = $request->getValue('title'); + $topic = $request->getValue('topic'); list($errors, $conpherence) = ConpherenceEditor::createThread( $request->getUser(), $participant_phids, $title, $message, - $request->newContentSource()); + $request->newContentSource(), + $topic); if ($errors) { foreach ($errors as $error_code) { switch ($error_code) { - case ConpherenceEditor::ERROR_EMPTY_MESSAGE: - throw new ConduitException('ERR_EMPTY_MESSAGE'); + case ConpherenceEditor::ERROR_EMPTY_TITLE: + throw new ConduitException('ERR_EMPTY_TITLE'); break; case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS: throw new ConduitException('ERR_EMPTY_PARTICIPANT_PHIDS'); diff --git a/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php b/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php deleted file mode 100644 index b8d84df082..0000000000 --- a/src/applications/conpherence/constants/ConpherenceWidgetConfigConstants.php +++ /dev/null @@ -1,42 +0,0 @@ - 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-settings' => array( - 'name' => pht('Notifications'), - 'icon' => 'fa-wrench', - 'deviceOnly' => false, - 'hasCreate' => false, - ), - ); - } - -} diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index b0c2f31fe9..227b3418fc 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -14,81 +14,78 @@ abstract class ConpherenceController extends PhabricatorController { public function buildApplicationMenu() { $nav = new PHUIListView(); + $conpherence = $this->conpherence; + // Local Links + if ($conpherence) { + $nav->addMenuItem( + id(new PHUIListItemView()) + ->setName(pht('Edit Room')) + ->setType(PHUIListItemView::TYPE_LINK) + ->setHref( + $this->getApplicationURI('update/'.$conpherence->getID()).'/') + ->setWorkflow(true)); + + $nav->addMenuItem( + id(new PHUIListItemView()) + ->setName(pht('Add Participants')) + ->setType(PHUIListItemView::TYPE_LINK) + ->setHref('#') + ->addSigil('conpherence-widget-adder') + ->setMetadata(array('widget' => 'widgets-people'))); + } + + // Global Links + $nav->newLabel(pht('Conpherence')); $nav->newLink( pht('New Room'), $this->getApplicationURI('new/')); - - $nav->addMenuItem( - id(new PHUIListItemView()) - ->setName(pht('Add Participants')) - ->setType(PHUIListItemView::TYPE_LINK) - ->setHref('#') - ->addSigil('conpherence-widget-adder') - ->setMetadata(array('widget' => 'widgets-people'))); + $nav->newLink( + pht('Search Rooms'), + $this->getApplicationURI('search/')); return $nav; } - protected function buildApplicationCrumbs() { - return $this->buildConpherenceApplicationCrumbs(); - } - - protected function buildConpherenceApplicationCrumbs($is_rooms = false) { - $crumbs = parent::buildApplicationCrumbs(); - $crumbs->setBorder(true); - - if (!$is_rooms) { - $crumbs - ->addAction( - id(new PHUIListItemView()) - ->setName(pht('Room')) - ->setHref('#') - ->setIcon('fa-bars') - ->setStyle('display: none;') - ->addClass('device-widgets-selector') - ->addSigil('device-widgets-selector')); - } - return $crumbs; - } - protected function buildHeaderPaneContent( ConpherenceThread $conpherence, array $policy_objects) { assert_instances_of($policy_objects, 'PhabricatorPolicy'); $viewer = $this->getViewer(); - - $crumbs = $this->buildApplicationCrumbs(); + $header = null; if ($conpherence->getID()) { $data = $conpherence->getDisplayData($this->getViewer()); - $crumbs->addCrumb( - id(new PHUICrumbView()) - ->setName($data['title']) - ->setHref('/'.$conpherence->getMonogram())); - $can_edit = PhabricatorPolicyFilter::hasCapability( + $header = id(new PHUIHeaderView()) + ->setHeader($data['title']) + ->setSubheader($data['topic']) + ->addClass((!$data['topic']) ? 'conpherence-no-topic' : null); + + $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $conpherence, PhabricatorPolicyCapability::CAN_EDIT); - $crumbs - ->addAction( - id(new PHUIListItemView()) - ->setName(pht('Edit Room')) + $header->addActionItem( + id(new PHUIIconCircleView()) ->setHref( $this->getApplicationURI('update/'.$conpherence->getID()).'/') ->setIcon('fa-pencil') - ->setDisabled(!$can_edit) + ->addClass('hide-on-device') + ->setWorkflow(true)); + + $header->addActionItem( + id(new PHUIIconCircleView()) + ->setHref( + $this->getApplicationURI('update/'.$conpherence->getID()).'/'. + '?action='.ConpherenceUpdateActions::NOTIFICATIONS) + ->setIcon('fa-gear') + ->addClass('hide-on-device') ->setWorkflow(true)); $widget_key = PhabricatorConpherenceWidgetVisibleSetting::SETTINGKEY; $widget_view = (bool)$viewer->getUserSetting($widget_key, false); - $divider = id(new PHUIListItemView()) - ->setType(PHUIListItemView::TYPE_DIVIDER) - ->addClass('conpherence-header-desktop-item'); - $crumbs->addAction($divider); - Javelin::initBehavior( 'toggle-widget', array( @@ -96,24 +93,15 @@ abstract class ConpherenceController extends PhabricatorController { 'settingsURI' => '/settings/adjust/?key='.$widget_key, )); - $crumbs->addAction( - id(new PHUIListItemView()) - ->addSigil('conpherence-widget-toggle') - ->setIcon('fa-columns') - ->addClass('conpherence-header-desktop-item')); + $header->addActionItem( + id(new PHUIIconCircleView()) + ->addSigil('conpherence-widget-toggle') + ->setIcon('fa-group') + ->setHref('#') + ->addClass('conpherence-participant-toggle')); } - return hsprintf( - '%s', - array( - phutil_tag( - 'div', - array( - 'class' => 'header-loading-mask', - ), - ''), - $crumbs, - )); + return $header; } } diff --git a/src/applications/conpherence/controller/ConpherenceNewRoomController.php b/src/applications/conpherence/controller/ConpherenceNewRoomController.php index 40dd6b2572..03df0859bd 100644 --- a/src/applications/conpherence/controller/ConpherenceNewRoomController.php +++ b/src/applications/conpherence/controller/ConpherenceNewRoomController.php @@ -26,6 +26,9 @@ final class ConpherenceNewRoomController extends ConpherenceController { $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setNewValue($request->getStr('title')); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransaction::TYPE_TOPIC) + ->setNewValue($request->getStr('topic')); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) ->setNewValue($request->getStr('viewPolicy')); @@ -93,6 +96,11 @@ final class ConpherenceNewRoomController extends ConpherenceController { ->setLabel(pht('Name')) ->setName('title') ->setValue($request->getStr('title'))) + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel(pht('Topic')) + ->setName('topic') + ->setValue($request->getStr('topic'))) ->appendChild( id(new AphrontFormTokenizerControl()) ->setName('participants') diff --git a/src/applications/conpherence/controller/ConpherenceParticipantController.php b/src/applications/conpherence/controller/ConpherenceParticipantController.php new file mode 100644 index 0000000000..353b7ad114 --- /dev/null +++ b/src/applications/conpherence/controller/ConpherenceParticipantController.php @@ -0,0 +1,73 @@ +getViewer(); + + $conpherence_id = $request->getURIData('id'); + if (!$conpherence_id) { + return new Aphront404Response(); + } + $conpherence = id(new ConpherenceThreadQuery()) + ->setViewer($viewer) + ->withIDs(array($conpherence_id)) + ->needWidgetData(true) + ->executeOne(); + if (!$conpherence) { + return new Aphront404Response(); + } + $this->setConpherence($conpherence); + $content = $this->renderParticipantPaneContent(); + + return id(new AphrontAjaxResponse())->setContent($content); + } + + private function renderParticipantPaneContent() { + $conpherence = $this->getConpherence(); + + $widgets = array(); + $new_icon = id(new PHUIIconView()) + ->setIcon('fa-plus-square') + ->setHref($this->getUpdateURI()) + ->setMetadata(array('widget' => null)) + ->addSigil('conpherence-widget-adder'); + + $content = id(new ConpherenceParticipantView()) + ->setUser($this->getViewer()) + ->setConpherence($this->getConpherence()) + ->setUpdateURI($this->getUpdateURI()); + + $widgets[] = phutil_tag( + 'div', + array( + 'class' => 'widgets-header', + ), + id(new PHUIHeaderView()) + ->setHeader(pht('Participants')) + ->addActionItem($new_icon)); + + $widgets[] = javelin_tag( + 'div', + array( + 'class' => 'widgets-body', + 'id' => 'widgets-people', + 'sigil' => 'widgets-people', + ), + $content); + + // without this implosion we get "," between each element in our widgets + // array + return array('widgets' => phutil_implode_html('', $widgets)); + } + + private function getUpdateURI() { + $conpherence = $this->getConpherence(); + return $this->getApplicationURI('update/'.$conpherence->getID().'/'); + } + +} diff --git a/src/applications/conpherence/controller/ConpherenceRoomListController.php b/src/applications/conpherence/controller/ConpherenceRoomListController.php index 704f210781..0e23c89a27 100644 --- a/src/applications/conpherence/controller/ConpherenceRoomListController.php +++ b/src/applications/conpherence/controller/ConpherenceRoomListController.php @@ -18,10 +18,6 @@ final class ConpherenceRoomListController extends ConpherenceController { return $this->delegateToController($controller); } - protected function buildApplicationCrumbs() { - return $this->buildConpherenceApplicationCrumbs($is_rooms = true); - } - public function buildApplicationMenu() { return $this->buildRoomsSideNavView(true)->getMenu(); } diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index 426377b9d9..4581058162 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -107,7 +107,7 @@ final class ConpherenceUpdateController break; case ConpherenceUpdateActions::REMOVE_PERSON: if (!$request->isContinueRequest()) { - // do nothing; we'll display a confirmation dialogue instead + // do nothing; we'll display a confirmation dialog instead break; } $person_phid = $request->getStr('remove_person'); @@ -127,22 +127,16 @@ final class ConpherenceUpdateController } $participant->setSettings(array('notifications' => $notifications)); $participant->save(); + return id(new AphrontRedirectResponse()) + ->setURI('/'.$conpherence->getMonogram()); - $label = PhabricatorConpherenceNotificationsSetting::getSettingLabel( - $notifications); - - $result = pht( - 'Updated notification settings to "%s".', - $label); - - return id(new AphrontAjaxResponse()) - ->setContent($result); break; case ConpherenceUpdateActions::METADATA: $top = $request->getInt('image_y'); $left = $request->getInt('image_x'); $file_id = $request->getInt('file_id'); $title = $request->getStr('title'); + $topic = $request->getStr('topic'); if ($file_id) { $orig_file = id(new PhabricatorFileQuery()) ->setViewer($user) @@ -190,9 +184,13 @@ final class ConpherenceUpdateController ->setNewValue($image_phid); } $title = $request->getStr('title'); + $topic = $request->getStr('topic'); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setNewValue($title); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransaction::TYPE_TOPIC) + ->setNewValue($topic); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) ->setNewValue($request->getStr('viewPolicy')); @@ -269,29 +267,97 @@ final class ConpherenceUpdateController } switch ($action) { + case ConpherenceUpdateActions::NOTIFICATIONS: + $dialog = $this->renderPreferencesDialog($conpherence); + break; case ConpherenceUpdateActions::ADD_PERSON: - $dialogue = $this->renderAddPersonDialogue($conpherence); + $dialog = $this->renderAddPersonDialog($conpherence); break; case ConpherenceUpdateActions::REMOVE_PERSON: - $dialogue = $this->renderRemovePersonDialogue($conpherence); + $dialog = $this->renderRemovePersonDialog($conpherence); break; case ConpherenceUpdateActions::METADATA: default: - $dialogue = $this->renderMetadataDialogue($conpherence, $error_view); + $dialog = $this->renderMetadataDialog($conpherence, $error_view); break; } - return id(new AphrontDialogResponse()) - ->setDialog($dialogue + return + $dialog ->setUser($user) ->setWidth(AphrontDialogView::WIDTH_FORM) ->setSubmitURI($this->getApplicationURI('update/'.$conpherence_id.'/')) ->addSubmitButton() - ->addCancelButton($this->getApplicationURI($conpherence->getID().'/'))); + ->addCancelButton($this->getApplicationURI($conpherence->getID().'/')); } - private function renderAddPersonDialogue( + private function renderPreferencesDialog( + ConpherenceThread $conpherence) { + + $request = $this->getRequest(); + $user = $request->getUser(); + + $participant = $conpherence->getParticipantIfExists($user->getPHID()); + if (!$participant) { + $can_join = PhabricatorPolicyFilter::hasCapability( + $user, + $conpherence, + PhabricatorPolicyCapability::CAN_JOIN); + if ($can_join) { + $text = pht( + 'Notification settings are available after joining the room.'); + } else if ($user->isLoggedIn()) { + $text = pht( + 'Notification settings not applicable to rooms you can not join.'); + } else { + $text = pht( + 'Notification settings are available after logging in and joining '. + 'the room.'); + } + return id(new AphrontDialogView()) + ->setTitle(pht('Room Preferences')) + ->appendParagraph($text); + } + + $notification_key = PhabricatorConpherenceNotificationsSetting::SETTINGKEY; + $notification_default = $user->getUserSetting($notification_key); + + $settings = $participant->getSettings(); + $notifications = idx( + $settings, + 'notifications', + $notification_default); + + $form = id(new AphrontFormView()) + ->setUser($user) + ->setFullWidth(true) + ->appendControl( + id(new AphrontFormRadioButtonControl()) + ->addButton( + PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL, + PhabricatorConpherenceNotificationsSetting::getSettingLabel( + PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL), + '') + ->addButton( + PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY, + PhabricatorConpherenceNotificationsSetting::getSettingLabel( + PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY), + '') + ->setName('notifications') + ->setValue($notifications)); + + return id(new AphrontDialogView()) + ->setTitle(pht('Room Preferences')) + ->addHiddenInput('action', 'notifications') + ->addHiddenInput( + 'latest_transaction_id', + $request->getInt('latest_transaction_id')) + ->appendForm($form); + + } + + private function renderAddPersonDialog( ConpherenceThread $conpherence) { $request = $this->getRequest(); @@ -322,7 +388,7 @@ final class ConpherenceUpdateController return $view; } - private function renderRemovePersonDialogue( + private function renderRemovePersonDialog( ConpherenceThread $conpherence) { $request = $this->getRequest(); @@ -405,7 +471,7 @@ final class ConpherenceUpdateController return $dialog; } - private function renderMetadataDialogue( + private function renderMetadataDialog( ConpherenceThread $conpherence, $error_view) { @@ -419,7 +485,12 @@ final class ConpherenceUpdateController id(new AphrontFormTextControl()) ->setLabel(pht('Title')) ->setName('title') - ->setValue($conpherence->getTitle())); + ->setValue($conpherence->getTitle())) + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel(pht('Topic')) + ->setName('topic') + ->setValue($conpherence->getTopic())); $nopic = $this->getRequest()->getExists('nopic'); $image = $conpherence->getImage(ConpherenceImageData::SIZE_ORIG); @@ -548,11 +619,10 @@ final class ConpherenceUpdateController $rendered_transactions = idx($data, 'transactions'); $new_latest_transaction_id = idx($data, 'latest_transaction_id'); - $widget_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/'); + $update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/'); $nav_item = null; $header = null; $people_widget = null; - $file_widget = null; if (!$minimal_display) { switch ($action) { case ConpherenceUpdateActions::METADATA: @@ -571,10 +641,10 @@ final class ConpherenceUpdateController $nav_item = hsprintf('%s', $nav_item); break; case ConpherenceUpdateActions::ADD_PERSON: - $people_widget = id(new ConpherencePeopleWidgetView()) + $people_widget = id(new ConpherenceParticipantView()) ->setUser($user) ->setConpherence($conpherence) - ->setUpdateURI($widget_uri); + ->setUpdateURI($update_uri); $people_widget = hsprintf('%s', $people_widget->render()); break; case ConpherenceUpdateActions::REMOVE_PERSON: @@ -595,7 +665,6 @@ final class ConpherenceUpdateController 'nav_item' => $nav_item, 'conpherence_phid' => $conpherence->getPHID(), 'header' => $header, - 'file_widget' => $file_widget, 'people_widget' => $people_widget, 'aphlictDropdownData' => array( $dropdown_query->getNotificationData(), diff --git a/src/applications/conpherence/controller/ConpherenceWidgetController.php b/src/applications/conpherence/controller/ConpherenceWidgetController.php deleted file mode 100644 index bfe8803cf9..0000000000 --- a/src/applications/conpherence/controller/ConpherenceWidgetController.php +++ /dev/null @@ -1,181 +0,0 @@ -getRequest(); - $user = $request->getUser(); - - $conpherence_id = $request->getURIData('id'); - if (!$conpherence_id) { - return new Aphront404Response(); - } - $conpherence = id(new ConpherenceThreadQuery()) - ->setViewer($user) - ->withIDs(array($conpherence_id)) - ->needWidgetData(true) - ->executeOne(); - if (!$conpherence) { - return new Aphront404Response(); - } - $this->setConpherence($conpherence); - - switch ($request->getStr('widget')) { - case 'widgets-people': - $content = $this->renderPeopleWidgetPaneContent(); - break; - case 'widgets-settings': - $content = $this->renderSettingsWidgetPaneContent(); - break; - default: - $widgets = $this->renderWidgetPaneContent(); - $content = $widgets; - break; - } - return id(new AphrontAjaxResponse())->setContent($content); - } - - private function renderWidgetPaneContent() { - $conpherence = $this->getConpherence(); - - $widgets = array(); - $new_icon = id(new PHUIIconView()) - ->setIcon('fa-plus') - ->setHref($this->getWidgetURI()) - ->setMetadata(array('widget' => null)) - ->addSigil('conpherence-widget-adder'); - $header = javelin_tag( - 'a', - array( - 'href' => '#', - 'sigil' => 'widgets-selector', - ), - pht('Participants')); - - $widgets[] = phutil_tag( - 'div', - array( - 'class' => 'widgets-header', - ), - id(new PHUIHeaderView()) - ->setHeader($header) - ->addActionItem($new_icon)); - $user = $this->getRequest()->getUser(); - // now the widget bodies - $widgets[] = javelin_tag( - 'div', - array( - 'class' => 'widgets-body', - 'id' => 'widgets-people', - 'sigil' => 'widgets-people', - ), - $this->renderPeopleWidgetPaneContent()); - $widgets[] = phutil_tag( - 'div', - array( - 'class' => 'widgets-body', - 'id' => 'widgets-settings', - 'style' => 'display: none', - ), - $this->renderSettingsWidgetPaneContent()); - - // without this implosion we get "," between each element in our widgets - // array - 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 renderSettingsWidgetPaneContent() { - $viewer = $this->getViewer(); - $conpherence = $this->getConpherence(); - $participant = $conpherence->getParticipantIfExists($viewer->getPHID()); - if (!$participant) { - $can_join = PhabricatorPolicyFilter::hasCapability( - $viewer, - $conpherence, - PhabricatorPolicyCapability::CAN_JOIN); - if ($can_join) { - $text = pht( - 'Notification settings are available after joining the room.'); - } else if ($viewer->isLoggedIn()) { - $text = pht( - 'Notification settings not applicable to rooms you can not join.'); - } else { - $text = pht( - 'Notification settings are available after logging in and joining '. - 'the room.'); - } - return phutil_tag( - 'div', - array( - 'class' => 'no-settings', - ), - $text); - } - $notification_key = PhabricatorConpherenceNotificationsSetting::SETTINGKEY; - $notification_default = $viewer->getUserSetting($notification_key); - - $settings = $participant->getSettings(); - $notifications = idx( - $settings, - 'notifications', - $notification_default); - $options = id(new AphrontFormRadioButtonControl()) - ->addButton( - PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL, - PhabricatorConpherenceNotificationsSetting::getSettingLabel( - PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_EMAIL), - '') - ->addButton( - PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY, - PhabricatorConpherenceNotificationsSetting::getSettingLabel( - PhabricatorConpherenceNotificationsSetting::VALUE_CONPHERENCE_NOTIFY), - '') - ->setName('notifications') - ->setValue($notifications); - - $layout = array( - $options, - phutil_tag( - 'input', - array( - 'type' => 'hidden', - 'name' => 'action', - 'value' => 'notifications', - )), - phutil_tag( - 'button', - array( - 'type' => 'submit', - 'class' => 'notifications-update', - ), - pht('Save')), - ); - - return phabricator_form( - $viewer, - array( - 'method' => 'POST', - 'action' => $this->getWidgetURI(), - 'sigil' => 'notifications-update', - ), - $layout); - } - - private function getWidgetURI() { - $conpherence = $this->getConpherence(); - return $this->getApplicationURI('update/'.$conpherence->getID().'/'); - } - -} diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php index 77dcf84eec..d1826ef98a 100644 --- a/src/applications/conpherence/editor/ConpherenceEditor.php +++ b/src/applications/conpherence/editor/ConpherenceEditor.php @@ -18,7 +18,8 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { array $participant_phids, $title, $message, - PhabricatorContentSource $source) { + PhabricatorContentSource $source, + $topic) { $conpherence = ConpherenceThread::initializeNewRoom($creator); $files = array(); @@ -59,6 +60,11 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) ->setNewValue($title); } + if (strlen($topic)) { + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransaction::TYPE_TOPIC) + ->setNewValue($topic); + } $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) @@ -118,6 +124,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = ConpherenceTransaction::TYPE_TITLE; + $types[] = ConpherenceTransaction::TYPE_TOPIC; $types[] = ConpherenceTransaction::TYPE_PARTICIPANTS; $types[] = ConpherenceTransaction::TYPE_FILES; $types[] = ConpherenceTransaction::TYPE_PICTURE; @@ -136,6 +143,8 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { switch ($xaction->getTransactionType()) { case ConpherenceTransaction::TYPE_TITLE: return $object->getTitle(); + case ConpherenceTransaction::TYPE_TOPIC: + return $object->getTopic(); case ConpherenceTransaction::TYPE_PICTURE: return $object->getImagePHID(ConpherenceImageData::SIZE_ORIG); case ConpherenceTransaction::TYPE_PICTURE_CROP: @@ -156,6 +165,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { switch ($xaction->getTransactionType()) { case ConpherenceTransaction::TYPE_TITLE: + case ConpherenceTransaction::TYPE_TOPIC: case ConpherenceTransaction::TYPE_PICTURE_CROP: return $xaction->getNewValue(); case ConpherenceTransaction::TYPE_PICTURE: @@ -250,6 +260,9 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { case ConpherenceTransaction::TYPE_TITLE: $object->setTitle($xaction->getNewValue()); break; + case ConpherenceTransaction::TYPE_TOPIC: + $object->setTopic($xaction->getNewValue()); + break; case ConpherenceTransaction::TYPE_PICTURE: $object->setImagePHID( $xaction->getNewValue(), @@ -484,6 +497,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { PhabricatorPolicyCapability::CAN_VIEW); break; case ConpherenceTransaction::TYPE_TITLE: + case ConpherenceTransaction::TYPE_TOPIC: PhabricatorPolicyFilter::requireCapability( $this->requireActor(), $object, diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php index 376a83899f..5a999f0422 100644 --- a/src/applications/conpherence/storage/ConpherenceThread.php +++ b/src/applications/conpherence/storage/ConpherenceThread.php @@ -8,6 +8,7 @@ final class ConpherenceThread extends ConpherenceDAO PhabricatorDestructibleInterface { protected $title; + protected $topic; protected $imagePHIDs = array(); protected $messageCount; protected $recentParticipantPHIDs = array(); @@ -29,6 +30,7 @@ final class ConpherenceThread extends ConpherenceDAO return id(new ConpherenceThread()) ->setMessageCount(0) ->setTitle('') + ->setTopic('') ->attachParticipants(array()) ->attachFilePHIDs(array()) ->attachImages(array()) @@ -46,6 +48,7 @@ final class ConpherenceThread extends ConpherenceDAO ), self::CONFIG_COLUMN_SCHEMA => array( 'title' => 'text255?', + 'topic' => 'text255', 'messageCount' => 'uint64', 'mailKey' => 'text20', 'joinPolicy' => 'policy', @@ -342,9 +345,11 @@ final class ConpherenceThread extends ConpherenceDAO $unread_count = $this->getMessageCount() - $user_seen_count; $title = $this->getDisplayTitle($viewer); + $topic = $this->getTopic(); return array( 'title' => $title, + 'topic' => $topic, 'subtitle' => $subtitle, 'unread_count' => $unread_count, 'epoch' => $this->getDateModified(), diff --git a/src/applications/conpherence/storage/ConpherenceTransaction.php b/src/applications/conpherence/storage/ConpherenceTransaction.php index 062b9e4a9f..4364276564 100644 --- a/src/applications/conpherence/storage/ConpherenceTransaction.php +++ b/src/applications/conpherence/storage/ConpherenceTransaction.php @@ -4,6 +4,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction { const TYPE_FILES = 'files'; const TYPE_TITLE = 'title'; + const TYPE_TOPIC = 'topic'; const TYPE_PARTICIPANTS = 'participants'; const TYPE_DATE_MARKER = 'date-marker'; const TYPE_PICTURE = 'picture'; @@ -39,6 +40,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction { case self::TYPE_PARTICIPANTS: return ($old === null); case self::TYPE_TITLE: + case self::TYPE_TOPIC: case self::TYPE_PICTURE: case self::TYPE_DATE_MARKER: return false; @@ -59,6 +61,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction { switch ($this->getTransactionType()) { case self::TYPE_TITLE: + case self::TYPE_TOPIC: case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY: case PhabricatorTransactions::TYPE_JOIN_POLICY: @@ -147,6 +150,20 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction { } return $title; break; + case self::TYPE_TOPIC: + if ($new) { + $title = pht( + '%s set the topic of this room to "%s".', + $this->renderHandleLink($author_phid), + $new); + } else if ($old) { + $title = pht( + '%s deleted the room topic "%s"', + $this->renderHandleLink($author_phid), + $old); + } + return $title; + break; case self::TYPE_PICTURE: return pht( '%s updated the room image.', diff --git a/src/applications/conpherence/view/ConpherenceLayoutView.php b/src/applications/conpherence/view/ConpherenceLayoutView.php index 7691ab9899..9b52cc3166 100644 --- a/src/applications/conpherence/view/ConpherenceLayoutView.php +++ b/src/applications/conpherence/view/ConpherenceLayoutView.php @@ -105,9 +105,7 @@ final class ConpherenceLayoutView extends AphrontView { $classes[] = 'hide-widgets'; } - $this->initBehavior( - 'conpherence-widget-pane', - ConpherenceWidgetConfigConstants::getWidgetPaneBehaviorConfig()); + $this->initBehavior('conpherence-participants-pane'); return javelin_tag( 'div', diff --git a/src/applications/conpherence/view/ConpherencePeopleWidgetView.php b/src/applications/conpherence/view/ConpherenceParticipantView.php similarity index 76% rename from src/applications/conpherence/view/ConpherencePeopleWidgetView.php rename to src/applications/conpherence/view/ConpherenceParticipantView.php index 0771e4f4a1..c5414d1d7a 100644 --- a/src/applications/conpherence/view/ConpherencePeopleWidgetView.php +++ b/src/applications/conpherence/view/ConpherenceParticipantView.php @@ -1,6 +1,25 @@ updateURI = $update_uri; + return $this; + } + public function getUpdateURI() { + return $this->updateURI; + } + + public function setConpherence(ConpherenceThread $conpherence) { + $this->conpherence = $conpherence; + return $this; + } + public function getConpherence() { + return $this->conpherence; + } public function render() { $conpherence = $this->getConpherence(); @@ -14,6 +33,7 @@ final class ConpherencePeopleWidgetView extends ConpherenceWidgetView { natcasesort($handle_list); $handles = mpull($handles, null, 'getName'); $handles = array_select_keys($handles, $handle_list); + $head_handles = mpull($head_handles, null, 'getName'); $handles = $head_handles + $handles; @@ -28,7 +48,8 @@ final class ConpherencePeopleWidgetView extends ConpherenceWidgetView { if (($user_phid == $viewer->getPHID()) || $can_edit) { $icon = id(new PHUIIconView()) - ->setIcon('fa-times lightbluetext'); + ->setIcon('fa-times') + ->addClass('lightbluetext'); $remove_html = javelin_tag( 'a', array( diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php index 48e0b15867..467ddf1411 100644 --- a/src/applications/conpherence/view/ConpherenceTransactionView.php +++ b/src/applications/conpherence/view/ConpherenceTransactionView.php @@ -231,6 +231,7 @@ final class ConpherenceTransactionView extends AphrontView { $content = $transaction->getTitle(); break; case ConpherenceTransaction::TYPE_TITLE: + case ConpherenceTransaction::TYPE_TOPIC: case ConpherenceTransaction::TYPE_PICTURE: case ConpherenceTransaction::TYPE_PICTURE_CROP: case ConpherenceTransaction::TYPE_PARTICIPANTS: diff --git a/src/applications/conpherence/view/ConpherenceWidgetView.php b/src/applications/conpherence/view/ConpherenceWidgetView.php deleted file mode 100644 index b3e704dcd9..0000000000 --- a/src/applications/conpherence/view/ConpherenceWidgetView.php +++ /dev/null @@ -1,24 +0,0 @@ -updateURI = $update_uri; - return $this; - } - public function getUpdateURI() { - return $this->updateURI; - } - - public function setConpherence(ConpherenceThread $conpherence) { - $this->conpherence = $conpherence; - return $this; - } - public function getConpherence() { - return $this->conpherence; - } - -} diff --git a/webroot/rsrc/css/aphront/dialog-view.css b/webroot/rsrc/css/aphront/dialog-view.css index 7328cda5ea..3122fd7e92 100644 --- a/webroot/rsrc/css/aphront/dialog-view.css +++ b/webroot/rsrc/css/aphront/dialog-view.css @@ -46,6 +46,10 @@ border: none; } +.device-phone .aphront-dialog-body { + padding: 8px; +} + .aphront-dialog-tail { border: none; position: relative; diff --git a/webroot/rsrc/css/application/conpherence/header-pane.css b/webroot/rsrc/css/application/conpherence/header-pane.css new file mode 100644 index 0000000000..0fda92fede --- /dev/null +++ b/webroot/rsrc/css/application/conpherence/header-pane.css @@ -0,0 +1,68 @@ +/** + * @provides conpherence-header-pane-css + */ + +.conpherence-header-pane { +} + +.conpherence-header-pane .phui-header-shell { + padding: 8px 16px 10px; + min-height: 38px; +} + +.conpherence-header-pane .phui-header-header { + font-size: 16px; + font-family: 'Aleo', {$fontfamily}; + color: #000; +} + +.conpherence-header-pane .phui-header-subheader { + color: {$lightgreyborder}; + padding: 0; + font-size: 12px; + margin: 0; +} + +.conpherence-header-pane .phui-header-shell.conpherence-no-topic { + padding: 15px 16px 5px; +} + +.conpherence-header-pane .phui-header-action-list .phui-header-action-item + .phui-icon-view { + height: 18px; + width: 24px; + font-size: 14px; + line-height: 23px; + display: block; +} + +.device .hide-on-device { + display: none; +} + +.device-phone .conpherence-header-pane .phui-header-col3 { + vertical-align: middle; +} + +.conpherence-header-pane .conpherence-participant-toggle.phui-icon-circle { + text-decoration: none; + border-color: {$sky}; + cursor: pointer; +} + +.conpherence-header-pane .conpherence-participant-toggle.phui-icon-circle + .phui-icon-view { + color: {$sky}; +} + +.hide-widgets .conpherence-header-pane + .conpherence-participant-toggle.phui-icon-circle { + text-decoration: none; + border-color: {$lightblueborder}; + cursor: pointer; +} + +.hide-widgets .conpherence-header-pane + .conpherence-participant-toggle.phui-icon-circle .phui-icon-view { + color: {$lightblueborder}; +} diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css index 868fd1a84e..954e4ef44b 100644 --- a/webroot/rsrc/css/application/conpherence/message-pane.css +++ b/webroot/rsrc/css/application/conpherence/message-pane.css @@ -9,7 +9,7 @@ position: fixed; left: 240px; right: 240px; - top: 76px; + top: 102px; bottom: 0px; min-width: 300px; width: auto; @@ -32,11 +32,6 @@ margin: 16px 0px 16px 0px; } -.conpherence-layout .phui-crumbs-view { - padding: 0 0 0 8px; - background: #f7f7f7; -} - .conpherence-show-more-messages { display: block; background: #e0e3ec; @@ -54,7 +49,7 @@ position: fixed; left: 240px; right: 240px; - top: 78px; + top: 103px; bottom: 148px; overflow-x: hidden; overflow-y: auto; @@ -103,13 +98,17 @@ .conpherence-message-pane .phui-form-view { border-width: 0; height: 140px; - padding: 0 8px 8px; + padding: 0 20px 12px; position: fixed; bottom: 0; left: 240px; right: 241px; } +.device .conpherence-message-pane .phui-form-view { + padding: 8px 8px; +} + .conpherence-message-pane .phui-form-view.login-to-participate { height: 26px; } @@ -123,6 +122,11 @@ margin-top: 6px; } +.device .conpherence-message-pane .aphront-form-control-submit button, +.device .conpherence-message-pane .aphront-form-control-submit a.button { + margin-top: 13px; +} + /** * When entering "Fullscreen Mode" in the remarkup control, we need to drop * all of the "position: fixed" on parent elements or Chrome doesn't put the @@ -162,7 +166,7 @@ .conpherence-message-pane .conpherence-transaction-view { padding: 2px 0px; - margin: 4px 12px; + margin: 4px 20px; background-size: 100%; min-height: auto; } @@ -182,7 +186,9 @@ } .device-phone .conpherence-message-pane .conpherence-transaction-image { - display: none; + height: 25px; + width: 25px; + background-size: 25px; } .conpherence-message-pane .conpherence-comment.anchor-target, @@ -206,12 +212,12 @@ } .device-phone .conpherence-message-pane .conpherence-transaction-detail { - margin: 0; + margin-left: 32px; } .conpherence-message-pane .conpherence-transaction-view.date-marker { padding: 0; - margin: 20px 12px 4px; + margin: 20px 20px 4px; min-height: auto; } @@ -234,7 +240,6 @@ .device .conpherence-message-pane .conpherence-transaction-view.date-marker .date { - color: {$lightbluetext}; left: 4px; } @@ -351,10 +356,3 @@ max-height: 200px; } -.device .conpherence-header-desktop-item { - display: none; -} - -.device .conpherence-header-pane .phui-crumb-action-divider { - display: none; -} diff --git a/webroot/rsrc/css/application/conpherence/transaction.css b/webroot/rsrc/css/application/conpherence/transaction.css index 94348ec760..62454c448e 100644 --- a/webroot/rsrc/css/application/conpherence/transaction.css +++ b/webroot/rsrc/css/application/conpherence/transaction.css @@ -17,14 +17,14 @@ } .conpherence-transaction-view.date-marker { - border-top: 1px solid {$thinblueborder}; + border-top: 1px solid {$sh-violetborder}; } .conpherence-transaction-view.date-marker .date { position: relative; top: -11px; background-color: #fff; - color: #000; + color: {$sh-violettext}; font-weight: bold; } diff --git a/webroot/rsrc/css/application/conpherence/update.css b/webroot/rsrc/css/application/conpherence/update.css index f5c6fb43b7..8b29c085ed 100644 --- a/webroot/rsrc/css/application/conpherence/update.css +++ b/webroot/rsrc/css/application/conpherence/update.css @@ -2,10 +2,6 @@ * @provides conpherence-update-css */ -.phabricator-standard-page-body .aphront-dialog-view { - margin: 20px auto 0px auto; -} - .aphront-dialog-view .conpherence-dialogue-drag-photo { border: 1px dashed #bfbfbf; padding: 10px 0px 10px 10px; diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css index 98f6d92bdd..2560f51bb2 100644 --- a/webroot/rsrc/css/application/conpherence/widget-pane.css +++ b/webroot/rsrc/css/application/conpherence/widget-pane.css @@ -2,11 +2,10 @@ * @provides conpherence-widget-pane-css */ -.conpherence-widget-pane, -.loading .widgets-loading-mask { +.conpherence-widget-pane { position: fixed; right: 0px; - top: 79px; + top: 103px; bottom: 0; width: 240px; border-width: 0 0 0 1px; @@ -15,20 +14,9 @@ overflow-y: auto; -webkit-overflow-scrolling: touch; } -.device .conpherence-widget-pane, -.device .loading .widgets-loading-mask { - top: 44px; - width: 100%; -} -.conpherence-widget-pane .widgets-loading-mask { - opacity: .6; - background: #fff; - display: none; -} - -.loading .widgets-loading-mask { - display: block; +.device .conpherence-widget-pane { + background-color: {$page.background}; } .conpherence-widget-pane .aphront-form-input { @@ -48,84 +36,20 @@ font-size: {$biggerfontsize}; } -.device .conpherence-widget-pane .widgets-header { - display: none; -} - -.conpherence-widget-pane .widgets-header .caret { - float: none; - height: 0px; - width: 0px; - margin: 10px 0 0 4px; - border-top-color: #000; -} - .conpherence-widget-pane .widgets-header .phui-icon-view.disabled { color: {$lightgreytext}; } -.device-desktop .conpherence-layout .device-widgets-selector { - display: none; -} - .conpherence-widget-pane .widgets-body { position: fixed; overflow-y: auto; bottom: 0; - top: 76px; - width: 100%; -} - -#widgets-settings { - padding: 3px 6px; -} - -.device-desktop .conpherence-widget-pane .widgets-body { - top: 115px; + top: 144px; width: 240px; } -.conpherence-widget-pane .widget-icon { - display: block; - height: 14px; - width: 14px; -} - -.conpherence-widget-pane .phabricator-remarkup-embed-layout-link { - padding-bottom: 1px; -} - -/* people widget */ -.conpherence-widget-pane .people-widget-header .add-people-widget { - padding: 10px 0 5px 0; - overflow: hidden; -} - -.conpherence-widget-pane .people-widget-header .add-people-widget -.aphront-form-control-tokenizer { - float: left; - width: 150px; - padding: 0px 0px 0px 10px -} - -.device .conpherence-widget-pane .people-widget-header .add-people-widget -.aphront-form-control-tokenizer { - width: 70%; -} - -.conpherence-widget-pane .people-widget-header .add-people-widget -.people-add-button { - float: right; - margin: 2px 8px 0px 0px; - padding: 3px 16px 4px 16px; -} - -#widgets-people { - margin-top: 4px; -} - .conpherence-widget-pane .person-entry { - padding: 4px 8px; + padding: 4px 4px 4px 8px; } .conpherence-widget-pane .person-entry:hover { @@ -173,35 +97,17 @@ color: #000; } -/* settings widget */ -.conpherence-widget-pane .title-update, -.conpherence-widget-pane .notifications-update { - margin: 3px 0px 0px 4px; -} - -.conpherence-widget-pane .no-settings { - width: 200px; - padding: 20px; - text-align: center; - color: {$greytext}; -} - -.device .conpherence-widget-pane .no-settings { - width: 60px; - margin: 0 auto 0 auto; -} - /****** Hide Widgets **********************************************************/ -.device-desktop .hide-widgets .conpherence-widget-pane { +.hide-widgets .conpherence-widget-pane { display: none; } -.device-desktop .hide-widgets .conpherence-message-pane, -.device-desktop .hide-widgets .loading .messages-loading-mask, -.device-desktop .hide-widgets .loading .messages-loading-icon, -.device-desktop .hide-widgets .conpherence-no-threads, -.device-desktop .hide-widgets .conpherence-message-pane .conpherence-messages, -.device-desktop .hide-widgets .conpherence-message-pane .phui-form-view { +.hide-widgets .conpherence-message-pane, +.hide-widgets .loading .messages-loading-mask, +.hide-widgets .loading .messages-loading-icon, +.hide-widgets .conpherence-no-threads, +.hide-widgets .conpherence-message-pane .conpherence-messages, +.hide-widgets .conpherence-message-pane .phui-form-view { right: 0; } diff --git a/webroot/rsrc/css/core/z-index.css b/webroot/rsrc/css/core/z-index.css index 5d787b694d..dd4ec7910f 100644 --- a/webroot/rsrc/css/core/z-index.css +++ b/webroot/rsrc/css/core/z-index.css @@ -150,6 +150,10 @@ div.jx-typeahead-results { z-index: 21; } +.conpherence-widget-pane { + z-index: 25; +} + .phuix-dropdown-menu { z-index: 32; } diff --git a/webroot/rsrc/js/application/conpherence/behavior-menu.js b/webroot/rsrc/js/application/conpherence/behavior-menu.js index 5b93815716..c27833259e 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-menu.js +++ b/webroot/rsrc/js/application/conpherence/behavior-menu.js @@ -241,7 +241,7 @@ JX.behavior('conpherence-menu', function(config) { if (!data.widget) { data.widget = getDefaultWidget(); } - var widget_uri = config.baseURI + 'widget/' + data.threadID + '/'; + var widget_uri = config.baseURI + 'participant/' + data.threadID + '/'; new JX.Workflow(widget_uri, {}) .setHandler(JX.bind(null, onWidgetResponse, data.threadID, data.widget)) .start(); diff --git a/webroot/rsrc/js/application/conpherence/behavior-participants-pane.js b/webroot/rsrc/js/application/conpherence/behavior-participants-pane.js new file mode 100644 index 0000000000..e4ba433ead --- /dev/null +++ b/webroot/rsrc/js/application/conpherence/behavior-participants-pane.js @@ -0,0 +1,112 @@ +/** + * @requires javelin-behavior + * javelin-dom + * javelin-stratcom + * javelin-workflow + * javelin-util + * phabricator-notification + * conpherence-thread-manager + * @provides javelin-behavior-conpherence-participants-pane + */ + +JX.behavior('conpherence-participants-pane', function() { + + /** + * Generified adding new stuff to widgets technology! + */ + JX.Stratcom.listen( + ['click'], + 'conpherence-widget-adder', + function (e) { + e.kill(); + + var threadManager = JX.ConpherenceThreadManager.getInstance(); + var href = threadManager._getUpdateURI(); + var latest_transaction_id = threadManager.getLatestTransactionID(); + var data = { + latest_transaction_id : latest_transaction_id, + action : 'add_person' + }; + + var workflow = new JX.Workflow(href, data) + .setHandler(function (r) { + var threadManager = JX.ConpherenceThreadManager.getInstance(); + threadManager.setLatestTransactionID(r.latest_transaction_id); + var root = JX.DOM.find(document, 'div', 'conpherence-layout'); + var messages = null; + try { + messages = JX.DOM.find(root, 'div', 'conpherence-messages'); + } catch (ex) { + } + if (messages) { + JX.DOM.appendContent(messages, JX.$H(r.transactions)); + JX.Stratcom.invoke('conpherence-redraw-thread', null, {}); + } + + try { + var people_root = JX.DOM.find(root, 'div', 'widgets-people'); + // update the people widget + JX.DOM.setContent( + people_root, + JX.$H(r.people_widget)); + } catch (ex) { + } + + }); + + threadManager.syncWorkflow(workflow, 'submit'); + } + ); + + JX.Stratcom.listen( + ['touchstart', 'mousedown'], + 'remove-person', + function (e) { + var threadManager = JX.ConpherenceThreadManager.getInstance(); + var href = threadManager._getUpdateURI(); + var data = e.getNodeData('remove-person'); + + // While the user is removing themselves, disable the notification + // update behavior. If we don't do this, the user can get an error + // when they remove themselves about permissions as the notification + // code tries to load what jist happened. + var loadedPhid = threadManager.getLoadedThreadPHID(); + threadManager.setLoadedThreadPHID(null); + + new JX.Workflow(href, data) + .setCloseHandler(function() { + threadManager.setLoadedThreadPHID(loadedPhid); + }) + // we re-direct to conpherence home so the thread manager will + // fix itself there + .setHandler(function(r) { + JX.$U(r.href).go(); + }) + .start(); + } + ); + + /* settings widget */ + var onsubmitSettings = function (e) { + e.kill(); + var form = e.getNode('tag:form'); + var button = JX.DOM.find(form, 'button'); + JX.Workflow.newFromForm(form) + .setHandler(JX.bind(this, function (r) { + new JX.Notification() + .setDuration(6000) + .setContent(r) + .show(); + button.disabled = ''; + JX.DOM.alterClass(button, 'disabled', false); + })) + .start(); + }; + + JX.Stratcom.listen( + ['submit', 'didSyntheticSubmit'], + 'notifications-update', + onsubmitSettings + ); + +}); diff --git a/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js b/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js index 70f375336e..1b36f8ff79 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js +++ b/webroot/rsrc/js/application/conpherence/behavior-toggle-widget.js @@ -14,6 +14,7 @@ JX.behavior('toggle-widget', function(config) { var node = JX.$('conpherence-main-layout'); config.show = !config.show; JX.DOM.alterClass(node, 'hide-widgets', !config.show); + JX.Stratcom.invoke('resize'); new JX.Request(config.settingsURI) .setData({value: (config.show ? 1 : 0)}) diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js deleted file mode 100644 index dfdf4bfd78..0000000000 --- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js +++ /dev/null @@ -1,382 +0,0 @@ -/** - * @requires javelin-behavior - * javelin-dom - * javelin-stratcom - * javelin-workflow - * javelin-util - * phabricator-notification - * javelin-behavior-device - * phuix-dropdown-menu - * phuix-action-list-view - * phuix-action-view - * conpherence-thread-manager - * @provides javelin-behavior-conpherence-widget-pane - */ - -JX.behavior('conpherence-widget-pane', function(config) { - - /** - * There can be race conditions around loading the messages or the widgets - * first. Keep track of what widgets we've loaded with this variable. - */ - var _loadedWidgetsID = null; - - /** - * At any given time there can be only one selected widget. Keep track of - * which one it is by the user-facing name for ease of use with - * PhabricatorDropdownMenuItems. - */ - var _selectedWidgetName = null; - - /** - * This is potentially built each time the user switches conpherence threads - * or when the result JX.Device.getDevice() changes from desktop to some - * other value. - */ - var buildDeviceWidgetSelector = function (data) { - var device_header = _getDeviceWidgetHeader(); - if (!device_header) { - return; - } - JX.DOM.show(device_header); - var device_menu = new JX.PHUIXDropdownMenu(device_header); - data.deviceMenu = true; - _buildWidgetSelector(device_menu, data); - }; - - /** - * This is potentially built each time the user switches conpherence threads - * or when the result JX.Device.getDevice() changes from mobile or tablet to - * desktop. - */ - var buildDesktopWidgetSelector = function (data) { - var root = JX.DOM.find(document, 'div', 'conpherence-layout'); - var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane'); - var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector'); - - var menu = new JX.PHUIXDropdownMenu(widget_header); - menu - .setAlign('left') - .setOffsetY(4); - - data.deviceMenu = false; - _buildWidgetSelector(menu, data); - }; - - /** - * Workhorse that actually builds the widget selector. Note some fancy bits - * where we listen for the "open" event and enable / disable widgets as - * appropos. - */ - var _buildWidgetSelector = function (menu, data) { - _loadedWidgetsID = data.threadID; - - var list = new JX.PHUIXActionListView(); - var map = {}; - - var widgets = config.widgetRegistry; - for (var widget in widgets) { - var widget_data = widgets[widget]; - if (widget_data.deviceOnly && data.deviceMenu === false) { - continue; - } - - var handler; - var href; - handler = JX.bind(null, function(widget, e) { - toggleWidget({widget: widget}); - e.prevent(); - menu.close(); - }, widget); - var item = new JX.PHUIXActionView() - .setIcon(widget_data.icon || 'none') - .setName(widget_data.name) - .setHref(href) - .setHandler(handler); - map[widget_data.name] = item; - list.addItem(item); - } - - menu - .setWidth(200) - .setContent(list.getNode()); - - menu.listen('open', function() { - for (var k in map) { - map[k].setDisabled((k == _selectedWidgetName)); - } - }); - }; - - /** - * Since this is not always on the page, avoid having a repeat - * try / catch block and consolidate into this helper function. - */ - var _getDeviceWidgetHeader = function () { - var root = JX.DOM.find(document, 'div', 'conpherence-layout'); - var device_header = null; - try { - device_header = JX.DOM.find( - root, - 'a', - 'device-widgets-selector'); - } catch (ex) { - // is okay - no deviceWidgetHeader yet... but bail time - } - return device_header; - }; - - /** - * Responder to the 'conpherence-did-redraw-thread' event, this bad boy - * hides or shows the device widget selector as appropros. - */ - var _didRedrawThread = function (data) { - if (_loadedWidgetsID === null || _loadedWidgetsID != data.threadID) { - return; - } - var device = JX.Device.getDevice(); - var device_selector = _getDeviceWidgetHeader(); - if (device == 'desktop') { - JX.DOM.hide(device_selector); - } else { - JX.DOM.show(device_selector); - } - if (data.buildDeviceWidgetSelector) { - buildDeviceWidgetSelector(data); - } - toggleWidget(data); - }; - JX.Stratcom.listen( - 'conpherence-did-redraw-thread', - null, - function (e) { - _didRedrawThread(e.getData()); - } - ); - - /** - * Toggling a widget involves showing / hiding the appropriate widget - * bodies as well as updating the selectors to have the label on the - * newly selected widget. - */ - var toggleWidget = function (data) { - var widgets = config.widgetRegistry; - var widget_data = widgets[data.widget]; - var device = JX.Device.getDevice(); - var is_desktop = device == 'desktop'; - - if (widget_data.deviceOnly && is_desktop) { - return; - } - _selectedWidgetName = widget_data.name; - - var device_header = _getDeviceWidgetHeader(); - if (device_header) { - // this is fragile but adding a sigil to this element is awkward - var device_header_spans = JX.DOM.scry(device_header, 'span'); - var device_header_span = device_header_spans[1]; - JX.DOM.setContent( - device_header_span, - widget_data.name); - } - - // don't update the non-device selector with device only widget stuff - if (!widget_data.deviceOnly) { - var root = JX.DOM.find(document, 'div', 'conpherence-layout'); - var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane'); - var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector'); - var adder = JX.DOM.find(widget_pane, 'a', 'conpherence-widget-adder'); - var threadManager = JX.ConpherenceThreadManager.getInstance(); - var disabled = !threadManager.getCanEditLoadedThread(); - JX.DOM.setContent( - widget_header, - widget_data.name); - JX.DOM.appendContent( - widget_header, - JX.$N('span', { className : 'caret' })); - if (widget_data.hasCreate) { - JX.DOM.show(adder); - JX.DOM.alterClass( - adder, - 'disabled', - disabled); - } else { - JX.DOM.hide(adder); - } - } - - for (var widget in config.widgetRegistry) { - widget_data = widgets[widget]; - if (widget_data.deviceOnly && is_desktop) { - // some one off code for conpherence messages which are device-only - // as a widget, but shown always on the desktop - if (widget == 'conpherence-message-pane') { - JX.$(widget).style.display = 'block'; - } - continue; - } - if (widget == data.widget) { - JX.$(widget).style.display = 'block'; - // some one off code for conpherence messages - fancier refresh tech - if (widget == 'conpherence-message-pane') { - JX.Stratcom.invoke('conpherence-redraw-thread', null, {}); - JX.Stratcom.invoke('conpherence-update-page-data', null, {}); - } - } else { - JX.$(widget).style.display = 'none'; - } - } - }; - - JX.Stratcom.listen( - 'conpherence-update-widgets', - null, - function (e) { - var data = e.getData(); - if (data.buildSelectors) { - buildDesktopWidgetSelector(data); - buildDeviceWidgetSelector(data); - } - if (data.toggleWidget) { - toggleWidget(data); - } - }); - - /** - * Generified adding new stuff to widgets technology! - */ - JX.Stratcom.listen( - ['click'], - 'conpherence-widget-adder', - function (e) { - e.kill(); - - var widgets = config.widgetRegistry; - // the widget key might be in node data, but otherwise use the - // selected widget - var event_data = e.getNodeData('conpherence-widget-adder'); - var widget_key = _selectedWidgetName; - if (event_data.widget) { - widget_key = widgets[event_data.widget].name; - } - - var widget_to_update = null; - var create_data = null; - for (var widget in widgets) { - if (widgets[widget].name == widget_key) { - create_data = widgets[widget].createData; - widget_to_update = widget; - break; - } - } - // this should be impossible, but hey - if (!widget_to_update) { - return; - } - var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/'; - if (create_data.customHref) { - href = create_data.customHref; - } - - var threadManager = JX.ConpherenceThreadManager.getInstance(); - var latest_transaction_id = threadManager.getLatestTransactionID(); - var data = { - latest_transaction_id : latest_transaction_id, - action : create_data.action - }; - - var workflow = new JX.Workflow(href, data) - .setHandler(function (r) { - var threadManager = JX.ConpherenceThreadManager.getInstance(); - threadManager.setLatestTransactionID(r.latest_transaction_id); - var root = JX.DOM.find(document, 'div', 'conpherence-layout'); - if (create_data.refreshFromResponse) { - var messages = null; - try { - messages = JX.DOM.find(root, 'div', 'conpherence-messages'); - } catch (ex) { - } - if (messages) { - JX.DOM.appendContent(messages, JX.$H(r.transactions)); - JX.Stratcom.invoke('conpherence-redraw-thread', null, {}); - } - - if (r.people_widget) { - try { - var people_root = JX.DOM.find(root, 'div', 'widgets-people'); - // update the people widget - JX.DOM.setContent( - people_root, - JX.$H(r.people_widget)); - } catch (ex) { - } - } - - // otherwise let's redraw the widget somewhat lazily - } else { - JX.Stratcom.invoke( - 'conpherence-reload-widget', - null, - { - threadID : _loadedWidgetsID, - widget : widget_to_update - }); - } - }); - - threadManager.syncWorkflow(workflow, 'submit'); - } - ); - - JX.Stratcom.listen( - ['touchstart', 'mousedown'], - 'remove-person', - function (e) { - var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/'; - var data = e.getNodeData('remove-person'); - - // While the user is removing themselves, disable the notification - // update behavior. If we don't do this, the user can get an error - // when they remove themselves about permissions as the notification - // code tries to load what jist happened. - var threadManager = JX.ConpherenceThreadManager.getInstance(); - var loadedPhid = threadManager.getLoadedThreadPHID(); - threadManager.setLoadedThreadPHID(null); - - new JX.Workflow(href, data) - .setCloseHandler(function() { - threadManager.setLoadedThreadPHID(loadedPhid); - }) - // we re-direct to conpherence home so the thread manager will - // fix itself there - .setHandler(function(r) { - JX.$U(r.href).go(); - }) - .start(); - } - ); - - /* settings widget */ - var onsubmitSettings = function (e) { - e.kill(); - var form = e.getNode('tag:form'); - var button = JX.DOM.find(form, 'button'); - JX.Workflow.newFromForm(form) - .setHandler(JX.bind(this, function (r) { - new JX.Notification() - .setDuration(6000) - .setContent(r) - .show(); - button.disabled = ''; - JX.DOM.alterClass(button, 'disabled', false); - })) - .start(); - }; - - JX.Stratcom.listen( - ['submit', 'didSyntheticSubmit'], - 'notifications-update', - onsubmitSettings - ); - -});