@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make Conpherence Pontificate Send-on-Enter

Summary: Fixes T11623. Enables send-on-enter and shift-enter for linebreaks, per durable column. Also cleaned up UI for Joining Room or Logging In.

Test Plan: See room I can join, click Join Room. Leave Room, Log out, visit room with login prompt. Login, Join Room again.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T11623

Differential Revision: https://secure.phabricator.com/D16595

+194 -113
+17 -17
resources/celerity/map.php
··· 7 7 */ 8 8 return array( 9 9 'names' => array( 10 - 'conpherence.pkg.css' => '80a3fcb3', 11 - 'conpherence.pkg.js' => '89b4837e', 12 - 'core.pkg.css' => 'f7b03076', 10 + 'conpherence.pkg.css' => '5722975a', 11 + 'conpherence.pkg.js' => '11f3e07e', 12 + 'core.pkg.css' => '2fd26498', 13 13 'core.pkg.js' => '1d376fa9', 14 14 'darkconsole.pkg.js' => 'e7393ebb', 15 15 'differential.pkg.css' => '3fb7f532', ··· 49 49 'rsrc/css/application/conpherence/durable-column.css' => '194ac487', 50 50 'rsrc/css/application/conpherence/header-pane.css' => '517de9fe', 51 51 'rsrc/css/application/conpherence/menu.css' => '78c7b811', 52 - 'rsrc/css/application/conpherence/message-pane.css' => '8d13ac4d', 52 + 'rsrc/css/application/conpherence/message-pane.css' => '1b49960e', 53 53 'rsrc/css/application/conpherence/notification.css' => '6cdcc253', 54 54 'rsrc/css/application/conpherence/participant-pane.css' => '7bba0b56', 55 55 'rsrc/css/application/conpherence/transaction.css' => '46253e19', ··· 138 138 'rsrc/css/phui/phui-document.css' => 'c32e8dec', 139 139 'rsrc/css/phui/phui-feed-story.css' => 'aa49845d', 140 140 'rsrc/css/phui/phui-fontkit.css' => '9cda225e', 141 - 'rsrc/css/phui/phui-form-view.css' => '76b4a46c', 141 + 'rsrc/css/phui/phui-form-view.css' => '9e22b190', 142 142 'rsrc/css/phui/phui-form.css' => 'aac1d51d', 143 143 'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f', 144 144 'rsrc/css/phui/phui-header-view.css' => '06385974', ··· 441 441 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'd3506890', 442 442 'rsrc/js/application/conpherence/behavior-menu.js' => '9eb55204', 443 443 'rsrc/js/application/conpherence/behavior-participant-pane.js' => '8604caa8', 444 - 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 444 + 'rsrc/js/application/conpherence/behavior-pontificate.js' => 'f2e58483', 445 445 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', 446 446 'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '9bdbbab0', 447 447 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', ··· 621 621 'conpherence-durable-column-view' => '194ac487', 622 622 'conpherence-header-pane-css' => '517de9fe', 623 623 'conpherence-menu-css' => '78c7b811', 624 - 'conpherence-message-pane-css' => '8d13ac4d', 624 + 'conpherence-message-pane-css' => '1b49960e', 625 625 'conpherence-notification-css' => '6cdcc253', 626 626 'conpherence-participant-pane-css' => '7bba0b56', 627 627 'conpherence-thread-manager' => '01774ab2', ··· 670 670 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', 671 671 'javelin-behavior-conpherence-menu' => '9eb55204', 672 672 'javelin-behavior-conpherence-participant-pane' => '8604caa8', 673 - 'javelin-behavior-conpherence-pontificate' => '21ba5861', 673 + 'javelin-behavior-conpherence-pontificate' => 'f2e58483', 674 674 'javelin-behavior-countdown-timer' => 'e4cc26b3', 675 675 'javelin-behavior-dark-console' => 'f411b6ae', 676 676 'javelin-behavior-dashboard-async-panel' => '469c0d9e', ··· 915 915 'phui-font-icon-base-css' => '870a7360', 916 916 'phui-fontkit-css' => '9cda225e', 917 917 'phui-form-css' => 'aac1d51d', 918 - 'phui-form-view-css' => '76b4a46c', 918 + 'phui-form-view-css' => '9e22b190', 919 919 'phui-head-thing-view-css' => 'fd311e5f', 920 920 'phui-header-view-css' => '06385974', 921 921 'phui-hovercard' => '1bd28176', ··· 1153 1153 'javelin-mask', 1154 1154 'javelin-uri', 1155 1155 'javelin-routable', 1156 - ), 1157 - '21ba5861' => array( 1158 - 'javelin-behavior', 1159 - 'javelin-dom', 1160 - 'javelin-util', 1161 - 'javelin-workflow', 1162 - 'javelin-stratcom', 1163 - 'conpherence-thread-manager', 1164 1156 ), 1165 1157 '21df4ff5' => array( 1166 1158 'javelin-install', ··· 2207 2199 ), 2208 2200 'f03e17be' => array( 2209 2201 'phui-theme-css', 2202 + ), 2203 + 'f2e58483' => array( 2204 + 'javelin-behavior', 2205 + 'javelin-dom', 2206 + 'javelin-util', 2207 + 'javelin-workflow', 2208 + 'javelin-stratcom', 2209 + 'conpherence-thread-manager', 2210 2210 ), 2211 2211 'f411b6ae' => array( 2212 2212 'javelin-behavior',
+1 -1
src/__phutil_library_map__.php
··· 4769 4769 'ConpherenceFulltextQuery' => 'PhabricatorOffsetPagedQuery', 4770 4770 'ConpherenceImageData' => 'ConpherenceConstants', 4771 4771 'ConpherenceIndex' => 'ConpherenceDAO', 4772 - 'ConpherenceLayoutView' => 'AphrontView', 4772 + 'ConpherenceLayoutView' => 'AphrontTagView', 4773 4773 'ConpherenceListController' => 'ConpherenceController', 4774 4774 'ConpherenceMenuItemView' => 'AphrontTagView', 4775 4775 'ConpherenceNewRoomController' => 'ConpherenceController',
+41 -3
src/applications/conpherence/controller/ConpherenceController.php
··· 62 62 ->addClass((!$data['topic']) ? 'conpherence-no-topic' : null); 63 63 64 64 $can_edit = PhabricatorPolicyFilter::hasCapability( 65 - $viewer, 66 - $conpherence, 67 - PhabricatorPolicyCapability::CAN_EDIT); 65 + $viewer, 66 + $conpherence, 67 + PhabricatorPolicyCapability::CAN_EDIT); 68 + 69 + $participating = $conpherence->getParticipantIfExists($viewer->getPHID()); 70 + $can_join = PhabricatorPolicyFilter::hasCapability( 71 + $viewer, 72 + $conpherence, 73 + PhabricatorPolicyCapability::CAN_JOIN); 68 74 69 75 $header->addActionItem( 70 76 id(new PHUIIconCircleView()) ··· 101 107 ->setIcon('fa-group') 102 108 ->setHref('#') 103 109 ->addClass('conpherence-participant-toggle')); 110 + 111 + if ($can_join && !$participating) { 112 + $action = ConpherenceUpdateActions::JOIN_ROOM; 113 + $uri = $this->getApplicationURI('update/'.$conpherence->getID().'/'); 114 + $button = phutil_tag( 115 + 'button', 116 + array( 117 + 'type' => 'SUBMIT', 118 + 'class' => 'button green mlr', 119 + ), 120 + pht('Join Room')); 121 + 122 + $hidden = phutil_tag( 123 + 'input', 124 + array( 125 + 'type' => 'hidden', 126 + 'name' => 'action', 127 + 'value' => ConpherenceUpdateActions::JOIN_ROOM, 128 + )); 129 + 130 + $form = phabricator_form( 131 + $viewer, 132 + array( 133 + 'method' => 'POST', 134 + 'action' => (string)$uri, 135 + ), 136 + array( 137 + $hidden, 138 + $button, 139 + )); 140 + $header->addActionItem($form); 141 + } 104 142 } 105 143 106 144 return $header;
+49 -28
src/applications/conpherence/controller/ConpherenceViewController.php
··· 118 118 return id(new AphrontAjaxResponse())->setContent($content); 119 119 } 120 120 121 + $can_join = PhabricatorPolicyFilter::hasCapability( 122 + $user, 123 + $conpherence, 124 + PhabricatorPolicyCapability::CAN_JOIN); 125 + 121 126 $layout = id(new ConpherenceLayoutView()) 122 127 ->setUser($user) 123 128 ->setBaseURI($this->getApplicationURI()) ··· 128 133 ->setLatestTransactionID($data['latest_transaction_id']) 129 134 ->setRole('thread'); 130 135 136 + $participating = $conpherence->getParticipantIfExists($user->getPHID()); 137 + 138 + if (!$user->isLoggedIn()) { 139 + $layout->addClass('conpherence-no-pontificate'); 140 + } 141 + 131 142 return $this->newPage() 132 143 ->setTitle($title) 133 144 ->setPageObjectPHIDs(array($conpherence->getPHID())) ··· 149 160 $draft = PhabricatorDraft::newFromUserAndKey( 150 161 $user, 151 162 $conpherence->getPHID()); 152 - if ($participating) { 153 - $action = ConpherenceUpdateActions::MESSAGE; 154 - $button_text = pht('Send'); 155 - } else if ($user->isLoggedIn()) { 156 - $action = ConpherenceUpdateActions::JOIN_ROOM; 157 - $button_text = pht('Join Room'); 163 + $update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/'); 164 + 165 + if ($user->isLoggedIn()) { 166 + $this->initBehavior('conpherence-pontificate'); 167 + if ($participating) { 168 + $action = ConpherenceUpdateActions::MESSAGE; 169 + $status = pht('I\'ll find something to put here.'); 170 + } else { 171 + $action = ConpherenceUpdateActions::JOIN_ROOM; 172 + $status = pht('Sending a message will also join the room.'); 173 + } 174 + 175 + $form = id(new AphrontFormView()) 176 + ->setUser($user) 177 + ->setAction($update_uri) 178 + ->addSigil('conpherence-pontificate') 179 + ->setWorkflow(true) 180 + ->addHiddenInput('action', $action) 181 + ->appendChild( 182 + id(new PhabricatorRemarkupControl()) 183 + ->setUser($user) 184 + ->setName('text') 185 + ->setValue($draft->getDraft())); 186 + 187 + $status_view = phutil_tag( 188 + 'div', 189 + array( 190 + 'class' => 'conpherence-room-status', 191 + 'id' => 'conpherence-room-status', 192 + ), 193 + $status); 194 + 195 + $view = phutil_tag_div( 196 + 'pontificate-container', array($form, $status_view)); 197 + 198 + return $view; 199 + 158 200 } else { 159 201 // user not logged in so give them a login button. 160 202 $login_href = id(new PhutilURI('/auth/start/')) 161 203 ->setQueryParam('next', '/'.$conpherence->getMonogram()); 162 204 return id(new PHUIFormLayoutView()) 163 205 ->addClass('login-to-participate') 206 + ->appendInstructions(pht('Log in to join this room and participate.')) 164 207 ->appendChild( 165 208 id(new PHUIButtonView()) 166 209 ->setTag('a') 167 210 ->setText(pht('Login to Participate')) 168 211 ->setHref((string)$login_href)); 169 212 } 170 - $update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/'); 171 - 172 - $this->initBehavior('conpherence-pontificate'); 173 - 174 - $form = 175 - id(new AphrontFormView()) 176 - ->setUser($user) 177 - ->setAction($update_uri) 178 - ->addSigil('conpherence-pontificate') 179 - ->setWorkflow(true) 180 - ->addHiddenInput('action', $action) 181 - ->appendChild( 182 - id(new PhabricatorRemarkupControl()) 183 - ->setUser($user) 184 - ->setName('text') 185 - ->setValue($draft->getDraft())) 186 - ->appendChild( 187 - id(new AphrontFormSubmitControl()) 188 - ->setValue($button_text)) 189 - ->render(); 190 - 191 - return $form; 192 213 } 193 214 194 215 private function getNeededTransactions(
+21 -24
src/applications/conpherence/view/ConpherenceLayoutView.php
··· 1 1 <?php 2 2 3 - final class ConpherenceLayoutView extends AphrontView { 3 + final class ConpherenceLayoutView extends AphrontTagView { 4 4 5 5 private $thread; 6 6 private $baseURI; ··· 61 61 return (bool)$user->getUserSetting($widget_key, false); 62 62 } 63 63 64 - public function render() { 64 + protected function getTagAttributes() { 65 + $classes = array(); 66 + if (!$this->getWidgetColumnVisible()) { 67 + $classes[] = 'hide-widgets'; 68 + } 69 + 70 + return array( 71 + 'id' => 'conpherence-main-layout', 72 + 'sigil' => 'conpherence-layout', 73 + 'class' => 'conpherence-layout '. 74 + implode(' ', $classes). 75 + ' conpherence-role-'.$this->role, 76 + ); 77 + 78 + } 79 + 80 + protected function getTagContent() { 65 81 require_celerity_resource('conpherence-menu-css'); 66 82 require_celerity_resource('conpherence-message-pane-css'); 67 83 require_celerity_resource('conpherence-participant-pane-css'); 68 - 69 - $layout_id = 'conpherence-main-layout'; 70 84 71 85 $selected_id = null; 72 86 $selected_thread_id = null; ··· 87 101 $this->initBehavior('conpherence-menu', 88 102 array( 89 103 'baseURI' => $this->baseURI, 90 - 'layoutID' => $layout_id, 104 + 'layoutID' => 'conpherence-main-layout', 91 105 'selectedID' => $selected_id, 92 106 'selectedThreadID' => $selected_thread_id, 93 107 'selectedThreadPHID' => $selected_thread_phid, ··· 98 112 'hasThread' => (bool)$this->messages, 99 113 'hasWidgets' => false, 100 114 )); 101 - 102 - $classes = array(); 103 - if (!$this->getUser()->isLoggedIn()) { 104 - $classes[] = 'conpherence-logged-out'; 105 - } 106 - 107 - if (!$this->getWidgetColumnVisible()) { 108 - $classes[] = 'hide-widgets'; 109 - } 110 115 111 116 $this->initBehavior('conpherence-participant-pane'); 112 117 113 - return javelin_tag( 114 - 'div', 115 - array( 116 - 'id' => $layout_id, 117 - 'sigil' => 'conpherence-layout', 118 - 'class' => 'conpherence-layout '. 119 - implode(' ', $classes). 120 - ' conpherence-role-'.$this->role, 121 - ), 118 + return 122 119 array( 123 120 javelin_tag( 124 121 'div', ··· 202 199 nonempty($this->replyForm, '')), 203 200 )), 204 201 )), 205 - )); 202 + ); 206 203 } 207 204 208 205 private function buildNUXView() {
+7 -7
src/view/form/AphrontFormView.php
··· 9 9 private $encType; 10 10 private $workflow; 11 11 private $id; 12 - private $shaded = false; 13 12 private $sigils = array(); 14 13 private $metadata; 15 14 private $controls = array(); 16 15 private $fullWidth = false; 16 + private $classes = array(); 17 17 18 18 public function setMetadata($metadata) { 19 19 $this->metadata = $metadata; ··· 44 44 return $this; 45 45 } 46 46 47 - public function setShaded($shaded) { 48 - $this->shaded = $shaded; 49 - return $this; 50 - } 51 - 52 47 public function addHiddenInput($key, $value) { 53 48 $this->data[$key] = $value; 54 49 return $this; ··· 61 56 62 57 public function addSigil($sigil) { 63 58 $this->sigils[] = $sigil; 59 + return $this; 60 + } 61 + 62 + public function addClass($class) { 63 + $this->classes[] = $class; 64 64 return $this; 65 65 } 66 66 ··· 149 149 return phabricator_form( 150 150 $this->getViewer(), 151 151 array( 152 - 'class' => $this->shaded ? 'phui-form-shaded' : null, 152 + 'class' => implode(' ', $this->classes), 153 153 'action' => $this->action, 154 154 'method' => $this->method, 155 155 'enctype' => $this->encType,
+33 -25
webroot/rsrc/css/application/conpherence/message-pane.css
··· 58 58 left: 240px; 59 59 right: 240px; 60 60 top: 103px; 61 - bottom: 148px; 61 + bottom: 122px; 62 62 overflow-x: hidden; 63 63 overflow-y: auto; 64 64 -webkit-overflow-scrolling: touch; 65 - } 66 - 67 - .conpherence-logged-out .conpherence-message-pane .conpherence-messages { 68 - bottom: 42px; 69 65 } 70 66 71 67 .conpherence-messages.jx-scrollbar-frame { ··· 77 73 padding-top: 20px; 78 74 } 79 75 80 - .conpherence-messages .jx-scrollbar-content .conpherence-edited:last-child { 76 + .conpherence-messages .conpherence-edited:last-child { 81 77 padding-bottom: 20px; 82 78 } 83 79 ··· 93 89 box-shadow: none; 94 90 } 95 91 96 - .conpherence-message-pane .messages-loading-mask { 97 - opacity: .6; 98 - background: #fff; 99 - display: none; 100 - } 101 - 102 - .loading .messages-loading-mask { 103 - display: block; 104 - } 105 - 106 92 .conpherence-message-pane .phui-form-view { 107 93 border-width: 0; 108 - height: 140px; 94 + height: 110px; 109 95 padding: 0 20px 12px; 110 96 position: fixed; 111 97 bottom: 0; ··· 113 99 right: 241px; 114 100 } 115 101 116 - .device .conpherence-message-pane .phui-form-view { 117 - padding: 8px 8px; 102 + .conpherence-room-status { 103 + font-size: {$smallerfontsize}; 104 + color: {$lightgreytext}; 105 + font-style: italic; 106 + position: absolute; 107 + bottom: 6px; 108 + left: 24px; 118 109 } 119 110 120 - .conpherence-message-pane .phui-form-view.login-to-participate { 121 - height: 26px; 111 + .conpherence-no-pontificate .conpherence-message-pane .phui-form-view { 112 + border-top: 1px solid {$thinblueborder}; 113 + text-align: center; 122 114 } 123 115 124 - .conpherence-message-pane .login-to-participate a.button { 125 - float: right; 116 + .conpherence-no-pontificate .conpherence-message-pane 117 + .aphront-form-control-submit button, 118 + .conpherence-no-pontificate .conpherence-message-pane 119 + .aphront-form-control-submit a.button { 120 + margin: 4px 0 0 0; 121 + float: none; 122 + } 123 + 124 + .conpherence-no-pontificate .phui-form-view .aphront-form-instructions { 125 + margin: 24px 0 16px; 126 + width: 100%; 127 + padding: 0; 128 + color: {$bluetext}; 129 + font-size: {$biggestfontsize}; 130 + } 131 + 132 + .device .conpherence-message-pane .phui-form-view { 133 + padding: 8px 8px; 126 134 } 127 135 128 136 .conpherence-message-pane .aphront-form-control-submit button, ··· 152 160 border-bottom: none; 153 161 border-top-left-radius: 3px; 154 162 border-top-right-radius: 3px; 155 - background-color: #f7f7f7; 163 + background-color: {$lightgreybackground}; 156 164 } 157 165 158 166 .device .conpherence-message-pane .remarkup-assist-bar { ··· 313 321 } 314 322 315 323 .conpherence-message-pane .remarkup-assist-textarea { 316 - height: 80px; 324 + height: 68px; 317 325 padding: 8px; 318 326 border: 2px solid {$lightgreyborder}; 319 327 border-top: 1px solid {$thinblueborder};
-6
webroot/rsrc/css/phui/phui-form-view.css
··· 14 14 padding: 0; 15 15 } 16 16 17 - /* only used in transaction comments */ 18 - .phui-form-shaded .phui-form-view { 19 - border-bottom: 1px solid #D4DAE0; 20 - background: #F4F5F8; 21 - } 22 - 23 17 .phui-form-view label.aphront-form-label { 24 18 padding-top: 5px; 25 19 width: 19%;
+25 -2
webroot/rsrc/js/application/conpherence/behavior-pontificate.js
··· 10 10 11 11 JX.behavior('conpherence-pontificate', function() { 12 12 13 - var onsubmit = function(e) { 13 + var _sendMessage = function(e) { 14 14 e.kill(); 15 15 var form = e.getNode('tag:form'); 16 16 var threadManager = JX.ConpherenceThreadManager.getInstance(); ··· 20 20 JX.Stratcom.listen( 21 21 ['submit', 'didSyntheticSubmit'], 22 22 'conpherence-pontificate', 23 - onsubmit); 23 + _sendMessage); 24 + 25 + // Send on enter if the shift key is not held. 26 + JX.Stratcom.listen( 27 + 'keydown', 28 + 'conpherence-pontificate', 29 + function(e) { 30 + if (e.getSpecialKey() != 'return') { 31 + return; 32 + } 33 + 34 + var raw = e.getRawEvent(); 35 + if (raw.shiftKey) { 36 + // If the shift key is pressed, let the browser write a newline into 37 + // the textarea. 38 + return; 39 + } 40 + 41 + // From here on, interpret this as a "send" action, not a literal 42 + // newline. 43 + e.kill(); 44 + 45 + _sendMessage(e); 46 + }); 24 47 25 48 });