@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.

Conpherence calendar updates

Summary: Fixes T3253 by shifting the display to the "next 3 days". Also adds in the "create" functionality for calendar on desktop view only, ref T3251. As part of T3251, I plan to make this work on mobile too.

Test Plan: added statuses and noted errors showed up. noted on success the widget pane refreshed. also made sure the regular old /calendar/status/create/ page still worked.

Reviewers: epriestley

Reviewed By: epriestley

CC: chad, aran, Korvin

Maniphest Tasks: T3251, T3253

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

+139 -38
+3 -3
src/__celerity_resource_map__.php
··· 945 945 ), 946 946 'conpherence-widget-pane-css' => 947 947 array( 948 - 'uri' => '/res/b218398a/rsrc/css/application/conpherence/widget-pane.css', 948 + 'uri' => '/res/e06804b6/rsrc/css/application/conpherence/widget-pane.css', 949 949 'type' => 'css', 950 950 'requires' => 951 951 array( ··· 1294 1294 ), 1295 1295 'javelin-behavior-conpherence-menu' => 1296 1296 array( 1297 - 'uri' => '/res/478fc4f3/rsrc/js/application/conpherence/behavior-menu.js', 1297 + 'uri' => '/res/87e901c2/rsrc/js/application/conpherence/behavior-menu.js', 1298 1298 'type' => 'js', 1299 1299 'requires' => 1300 1300 array( ··· 1325 1325 ), 1326 1326 'javelin-behavior-conpherence-widget-pane' => 1327 1327 array( 1328 - 'uri' => '/res/232893cf/rsrc/js/application/conpherence/behavior-widget-pane.js', 1328 + 'uri' => '/res/3b06849a/rsrc/js/application/conpherence/behavior-widget-pane.js', 1329 1329 'type' => 'js', 1330 1330 'requires' => 1331 1331 array(
+43 -7
src/applications/calendar/controller/PhabricatorCalendarEditStatusController.php
··· 86 86 'Y'), 87 87 $redirect => true, 88 88 )); 89 - return id(new AphrontRedirectResponse()) 90 - ->setURI($uri); 89 + if ($request->isAjax()) { 90 + $response = id(new AphrontAjaxResponse()) 91 + ->setContent(array('redirect_uri' => $uri)); 92 + } else { 93 + $response = id(new AphrontRedirectResponse()) 94 + ->setURI($uri); 95 + } 96 + return $response; 91 97 } 92 98 } 93 99 ··· 109 115 ->setName('description') 110 116 ->setValue($status->getDescription()); 111 117 112 - $form = id(new AphrontFormView()) 113 - ->setUser($user) 114 - ->setFlexible(true) 118 + if ($request->isAjax()) { 119 + $dialog = id(new AphrontDialogView()) 120 + ->setUser($user) 121 + ->setTitle($page_title) 122 + ->setWidth(AphrontDialogView::WIDTH_FORM); 123 + if ($this->isCreate()) { 124 + $dialog->setSubmitURI($this->getApplicationURI('status/create/')); 125 + } else { 126 + $dialog->setSubmitURI( 127 + $this->getApplicationURI('status/edit/'.$status->getID().'/')); 128 + } 129 + $form = new AphrontFormLayoutView(); 130 + if ($error_view) { 131 + $form->appendChild($error_view); 132 + } 133 + } else { 134 + $form = id(new AphrontFormView()) 135 + ->setUser($user) 136 + ->setFlexible(true); 137 + } 138 + 139 + $form 115 140 ->appendChild($status_select) 116 141 ->appendChild($start_time) 117 142 ->appendChild($end_time) 118 143 ->appendChild($description); 119 144 120 - $submit = id(new AphrontFormSubmitControl()) 121 - ->setValue($submit_label); 145 + if ($request->isAjax()) { 146 + $dialog->addSubmitButton($submit_label); 147 + $submit = $dialog; 148 + } else { 149 + $submit = id(new AphrontFormSubmitControl()) 150 + ->setValue($submit_label); 151 + } 122 152 if ($this->isCreate()) { 123 153 $submit->addCancelButton($this->getApplicationURI()); 124 154 } else { 125 155 $submit->addCancelButton( 126 156 $this->getApplicationURI('status/delete/'.$status->getID().'/'), 127 157 pht('Delete Status')); 158 + } 159 + 160 + if ($request->isAjax()) { 161 + $dialog->appendChild($form); 162 + return id(new AphrontDialogResponse()) 163 + ->setDialog($dialog); 128 164 } 129 165 $form->appendChild($submit); 130 166
+1
src/applications/conpherence/constants/ConpherenceUpdateActions.php
··· 7 7 const ADD_PERSON = 'add_person'; 8 8 const REMOVE_PERSON = 'remove_person'; 9 9 const NOTIFICATIONS = 'notifications'; 10 + const ADD_STATUS = 'add_status'; 10 11 }
+14 -13
src/applications/conpherence/controller/ConpherenceWidgetController.php
··· 65 65 $conpherence = $this->getConpherence(); 66 66 67 67 $widgets = array(); 68 + $new_icon = id(new PHUIIconView()) 69 + ->setSpriteSheet(PHUIIconView::SPRITE_ACTIONS) 70 + ->setSpriteIcon('new-grey') 71 + ->setHref($this->getWidgetURI()) 72 + ->addSigil('conpherence-widget-adder'); 68 73 $widgets[] = phutil_tag( 69 74 'div', 70 75 array( ··· 75 80 ->setHeaderTitle(pht('Participants')) 76 81 ->setHeaderHref('#') 77 82 ->setDropdown(true) 83 + ->addAction($new_icon) 78 84 ->addHeaderSigil('widgets-selector')); 79 85 $user = $this->getRequest()->getUser(); 80 86 // now the widget bodies ··· 193 199 $content = array(); 194 200 $layout = id(new AphrontMultiColumnView()) 195 201 ->setFluidLayout(true); 196 - $timestamps = $this->getCalendarWidgetWeekTimestamps(); 202 + $timestamps = $this->getCalendarWidgetTimestamps(); 197 203 $today = $timestamps['today']; 198 - $weekstamps = $timestamps['weekstamps']; 204 + $epoch_stamps = $timestamps['epoch_stamps']; 199 205 $one_day = 24 * 60 * 60; 200 - foreach ($weekstamps as $time => $day) { 206 + foreach ($epoch_stamps as $time => $day) { 201 207 // build a header for the new day 202 208 if ($day->format('w') == $today->format('w')) { 203 209 $active_class = 'today'; ··· 226 232 )); 227 233 228 234 $week_day_number = $day->format('w'); 229 - 230 235 231 236 $day->setTime(0, 0, 0); 232 237 $epoch_start = $day->format('U'); ··· 371 376 ); 372 377 } 373 378 374 - private function getCalendarWidgetWeekTimestamps() { 379 + private function getCalendarWidgetTimestamps() { 375 380 $user = $this->getRequest()->getUser(); 376 381 $timezone = new DateTimeZone($user->getTimezoneIdentifier()); 377 382 378 - $today = id(new DateTime('now', $timezone)); 379 - $monday = clone $today; 380 - $monday 381 - ->modify('+1 day') 382 - ->modify('last monday'); 383 + $today = id(new DateTime('today', $timezone)); 383 384 $timestamps = array(); 384 - for ($day = 0; $day < 7; $day++) { 385 - $timestamp = clone $monday; 385 + for ($day = 0; $day < 3; $day++) { 386 + $timestamp = clone $today; 386 387 $timestamps[] = $timestamp->modify(sprintf('+%d days', $day)); 387 388 } 388 389 389 390 return array( 390 391 'today' => $today, 391 - 'weekstamps' => $timestamps 392 + 'epoch_stamps' => $timestamps 392 393 ); 393 394 } 394 395
+7 -7
src/applications/conpherence/query/ConpherenceThreadQuery.php
··· 217 217 $file_phids = array_mergev($file_phids); 218 218 219 219 // statuses of everyone currently in the conpherence 220 - // for a rolling one week window 221 - $start_of_week = phabricator_format_local_time( 222 - strtotime('last monday', strtotime('tomorrow')), 220 + // for a rolling three day window 221 + $start_epoch = phabricator_format_local_time( 222 + strtotime('today', strtotime('tomorrow')), 223 223 $this->getViewer(), 224 224 'U'); 225 - $end_of_week = phabricator_format_local_time( 226 - strtotime('last monday +1 week', strtotime('tomorrow')), 225 + $end_epoch = phabricator_format_local_time( 226 + strtotime('+3 days', strtotime('tomorrow')), 227 227 $this->getViewer(), 228 228 'U'); 229 229 $statuses = id(new PhabricatorUserStatus()) 230 230 ->loadAllWhere( 231 231 'userPHID in (%Ls) AND dateTo >= %d AND dateFrom <= %d', 232 232 $participant_phids, 233 - $start_of_week, 234 - $end_of_week); 233 + $start_epoch, 234 + $end_epoch); 235 235 $statuses = mgroup($statuses, 'getUserPHID'); 236 236 237 237 // attached files
+6
src/applications/conpherence/view/ConpherenceLayoutView.php
··· 82 82 'conpherence-message-pane' => array( 83 83 'name' => pht('Thread'), 84 84 'deviceOnly' => true, 85 + 'hasCreate' => false 85 86 ), 86 87 'widgets-people' => array( 87 88 'name' => pht('Participants'), 88 89 'deviceOnly' => false, 90 + 'hasCreate' => false 89 91 ), 90 92 'widgets-files' => array( 91 93 'name' => pht('Files'), 92 94 'deviceOnly' => false, 95 + 'hasCreate' => false 93 96 ), 94 97 'widgets-calendar' => array( 95 98 'name' => pht('Calendar'), 96 99 'deviceOnly' => false, 100 + 'hasCreate' => true, 101 + 'createHref' => '/calendar/status/create/' 97 102 ), 98 103 'widgets-settings' => array( 99 104 'name' => pht('Settings'), 100 105 'deviceOnly' => false, 106 + 'hasCreate' => false 101 107 ), 102 108 ))); 103 109
+1 -1
webroot/rsrc/css/application/conpherence/widget-pane.css
··· 145 145 /* calendar widget */ 146 146 147 147 .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view { 148 - margin: 2px 0px 0px 0px; 149 148 width: 240px; 150 149 } 151 150 .device .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view { 151 + margin: 2px 0px 0px 0px; 152 152 width: 100%; 153 153 } 154 154 .conpherence-widget-pane #widgets-calendar .aphront-multi-column-view
+25 -7
webroot/rsrc/js/application/conpherence/behavior-menu.js
··· 138 138 } 139 139 140 140 if (_thread.visible !== null || !config.hasWidgets) { 141 - markWidgetLoading(true); 142 - var widget_uri = config.baseURI + 'widget/' + data.threadID + '/'; 143 - new JX.Workflow(widget_uri, {}) 144 - .setHandler(JX.bind(null, onWidgetResponse, data.threadID)) 145 - .start(); 141 + reloadWidget(data); 146 142 } else { 147 143 JX.Stratcom.invoke( 148 144 'conpherence-update-widgets', ··· 191 187 JX.DOM.alterClass(widgets_root, 'loading', loading); 192 188 } 193 189 194 - function onWidgetResponse(thread_id, response) { 190 + function reloadWidget(data) { 191 + markWidgetLoading(true); 192 + if (!data.widget) { 193 + data.widget = getDefaultWidget(); 194 + } 195 + var widget_uri = config.baseURI + 'widget/' + data.threadID + '/'; 196 + new JX.Workflow(widget_uri, {}) 197 + .setHandler(JX.bind(null, onWidgetResponse, data.threadID, data.widget)) 198 + .start(); 199 + } 200 + JX.Stratcom.listen( 201 + 'conpherence-reload-widget', 202 + null, 203 + function (e) { 204 + var data = e.getData(); 205 + if (data.threadID != _thread.selected) { 206 + return; 207 + } 208 + reloadWidget(data); 209 + } 210 + ); 211 + 212 + function onWidgetResponse(thread_id, widget, response) { 195 213 // we got impatient and this is no longer the right answer :/ 196 214 if (_thread.selected != thread_id) { 197 215 return; ··· 204 222 'conpherence-update-widgets', 205 223 null, 206 224 { 207 - widget : getDefaultWidget(), 225 + widget : widget, 208 226 buildSelectors : true, 209 227 toggleWidget : true, 210 228 threadID : _thread.selected
+39
webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
··· 169 169 var root = JX.DOM.find(document, 'div', 'conpherence-layout'); 170 170 var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane'); 171 171 var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector'); 172 + var adder = JX.DOM.find(widget_pane, 'a', 'conpherence-widget-adder'); 172 173 JX.DOM.setContent( 173 174 widget_header, 174 175 widget_data.name); 175 176 JX.DOM.appendContent( 176 177 widget_header, 177 178 JX.$N('span', { className : 'caret' })); 179 + if (widget_data.hasCreate) { 180 + JX.DOM.show(adder); 181 + } else { 182 + JX.DOM.hide(adder); 183 + } 178 184 } 179 185 180 186 for (var widget in config.widgetRegistry) { ··· 214 220 toggleWidget(data); 215 221 } 216 222 }); 223 + 224 + /** 225 + * Generified adding new stuff to widgets technology! 226 + */ 227 + JX.Stratcom.listen( 228 + ['click'], 229 + 'conpherence-widget-adder', 230 + function (e) { 231 + e.kill(); 232 + var widgets = config.widgetRegistry; 233 + var active_widget = null; 234 + var href = null; 235 + for (var widget in widgets) { 236 + if (widgets[widget].name == _selectedWidgetName) { 237 + href = widgets[widget].createHref; 238 + active_widget = widget; 239 + break; 240 + } 241 + } 242 + new JX.Workflow(href, {}) 243 + .setHandler(function () { 244 + JX.Stratcom.invoke( 245 + 'conpherence-reload-widget', 246 + null, 247 + { 248 + threadID : _loadedWidgetsID, 249 + widget : active_widget 250 + } 251 + ); 252 + }) 253 + .start(); 254 + } 255 + ); 217 256 218 257 /* people widget */ 219 258 JX.Stratcom.listen(