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

Renders the last 100 conpherence transactions only

Summary: Fixed T2428 a little bit

Test Plan: On trial, only the last n transactions loaded as hardcoded in ConpherenceViewController.php. Button was rendered.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2428

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

authored by

Deedy and committed by
epriestley
638d1b44 9da0a460

+378 -279
+2 -2
src/__celerity_resource_map__.php
··· 762 762 ), 763 763 'conpherence-message-pane-css' => 764 764 array( 765 - 'uri' => '/res/88b1927c/rsrc/css/application/conpherence/message-pane.css', 765 + 'uri' => '/res/3aa15b9e/rsrc/css/application/conpherence/message-pane.css', 766 766 'type' => 'css', 767 767 'requires' => 768 768 array( ··· 1142 1142 ), 1143 1143 'javelin-behavior-conpherence-menu' => 1144 1144 array( 1145 - 'uri' => '/res/986774a0/rsrc/js/application/conpherence/behavior-menu.js', 1145 + 'uri' => '/res/0ad6ab54/rsrc/js/application/conpherence/behavior-menu.js', 1146 1146 'type' => 'js', 1147 1147 'requires' => 1148 1148 array(
+4
src/__phutil_library_map__.php
··· 223 223 'ConpherenceTransactionView' => 'applications/conpherence/view/ConpherenceTransactionView.php', 224 224 'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php', 225 225 'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php', 226 + 'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php', 226 227 'DarkConsoleController' => 'aphront/console/DarkConsoleController.php', 227 228 'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.php', 228 229 'DarkConsoleDataController' => 'aphront/console/DarkConsoleDataController.php', ··· 1743 1744 'ConpherenceTransactionView' => 'AphrontView', 1744 1745 'ConpherenceUpdateController' => 'ConpherenceController', 1745 1746 'ConpherenceViewController' => 'ConpherenceController', 1747 + 'ConpherenceWidgetController' => 'ConpherenceController', 1746 1748 'DarkConsoleController' => 'PhabricatorController', 1747 1749 'DarkConsoleDataController' => 'PhabricatorController', 1748 1750 'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin', ··· 2056 2058 array( 2057 2059 0 => 'ManiphestDAO', 2058 2060 1 => 'PhabricatorMarkupInterface', 2061 + 2 => 'PhabricatorPolicyInterface', 2062 + 3 => 'PhabricatorTokenReceiverInterface', 2059 2063 ), 2060 2064 'ManiphestTaskAuxiliaryStorage' => 'ManiphestDAO', 2061 2065 'ManiphestTaskDescriptionChangeController' => 'ManiphestController',
+1
src/applications/conpherence/application/PhabricatorApplicationConpherence.php
··· 45 45 '' => 'ConpherenceListController', 46 46 'new/' => 'ConpherenceNewController', 47 47 'view/(?P<id>[1-9]\d*)/' => 'ConpherenceViewController', 48 + 'widget/(?P<id>[1-9]\d*)/' => 'ConpherenceWidgetController', 48 49 'update/(?P<id>[1-9]\d*)/' => 'ConpherenceUpdateController', 49 50 '(?P<id>[1-9]\d*)/' => 'ConpherenceListController', 50 51 ),
-4
src/applications/conpherence/controller/ConpherenceController.php
··· 101 101 $read_conpherences = $this->getReadConpherences(); 102 102 103 103 $user = $this->getRequest()->getUser(); 104 - 105 104 $menu = new PhabricatorMenuView(); 106 105 $nav = AphrontSideNavFilterView::newFromMenu($menu); 107 106 $nav->addClass('conpherence-menu'); ··· 114 113 ); 115 114 $nav->addLabel(pht('Unread')); 116 115 $nav = $this->addConpherencesToNav($unread_conpherences, $nav); 117 - 118 116 $nav->addLabel(pht('Read')); 119 117 $nav = $this->addConpherencesToNav($read_conpherences, $nav, true); 120 - 121 118 $nav->selectFilter($filter); 122 - 123 119 return $nav; 124 120 } 125 121
+14 -270
src/applications/conpherence/controller/ConpherenceViewController.php
··· 37 37 if (!$conpherence_id) { 38 38 return new Aphront404Response(); 39 39 } 40 - if (!$request->isAjax()) { 41 - return id(new AphrontRedirectResponse()) 42 - ->setURI($this->getApplicationURI($conpherence_id.'/')); 43 - } 44 40 $conpherence = id(new ConpherenceThreadQuery()) 45 41 ->setViewer($user) 46 42 ->withIDs(array($conpherence_id)) 47 - ->needWidgetData(true) 48 43 ->needHeaderPics(true) 49 44 ->executeOne(); 50 45 $this->setConpherence($conpherence); ··· 58 53 59 54 $header = $this->renderHeaderPaneContent(); 60 55 $messages = $this->renderMessagePaneContent(); 61 - $widgets = $this->renderWidgetPaneContent(); 62 - $content = $header + $widgets + $messages; 63 - 56 + $content = $header + $messages; 64 57 return id(new AphrontAjaxResponse())->setContent($content); 65 58 } 66 59 ··· 125 118 $handles = $conpherence->getHandles(); 126 119 $rendered_transactions = array(); 127 120 128 - $transactions = $conpherence->getTransactions(); 121 + 122 + $transactions = $conpherence->getTransactionsFrom(0, 100); 129 123 130 124 $engine = id(new PhabricatorMarkupEngine()) 131 125 ->setViewer($user); ··· 137 131 } 138 132 } 139 133 $engine->process(); 140 - 141 134 foreach ($transactions as $transaction) { 142 135 if ($transaction->shouldHide()) { 143 136 continue; ··· 168 161 ->setValue(pht('Pontificate')) 169 162 )->render(); 170 163 171 - return array( 172 - 'messages' => $transactions, 173 - 'form' => $form 174 - ); 175 - 176 - } 177 - 178 - private function renderWidgetPaneContent() { 179 - require_celerity_resource('conpherence-widget-pane-css'); 180 - require_celerity_resource('sprite-conpher-css'); 181 - Javelin::initBehavior( 182 - 'conpherence-widget-pane', 183 - array( 184 - 'widgetRegistery' => array( 185 - 'widgets-files' => 1, 186 - 'widgets-tasks' => 1, 187 - 'widgets-calendar' => 1, 188 - ) 189 - ) 190 - ); 191 - 192 - $conpherence = $this->getConpherence(); 193 - 194 - $widgets = phutil_tag( 195 - 'div', 196 - array( 197 - 'class' => 'widgets-header' 198 - ), 199 - array( 200 - javelin_tag( 201 - 'a', 202 - array( 203 - 'sigil' => 'conpherence-change-widget', 204 - 'meta' => array( 205 - 'widget' => 'widgets-files', 206 - 'toggleClass' => 'conpher_files_on' 207 - ), 208 - 'id' => 'widgets-files-toggle', 209 - 'class' => 'sprite-conpher conpher_files_off first-icon' 210 - ), 211 - '' 212 - ), 213 - javelin_tag( 214 - 'a', 215 - array( 216 - 'sigil' => 'conpherence-change-widget', 217 - 'meta' => array( 218 - 'widget' => 'widgets-tasks', 219 - 'toggleClass' => 'conpher_list_on' 220 - ), 221 - 'id' => 'widgets-tasks-toggle', 222 - 'class' => 'sprite-conpher conpher_list_off conpher_list_on', 223 - ), 224 - '' 225 - ), 226 - javelin_tag( 227 - 'a', 228 - array( 229 - 'sigil' => 'conpherence-change-widget', 230 - 'meta' => array( 231 - 'widget' => 'widgets-calendar', 232 - 'toggleClass' => 'conpher_calendar_on' 233 - ), 234 - 'id' => 'widgets-calendar-toggle', 235 - 'class' => 'sprite-conpher conpher_calendar_off', 236 - ), 237 - '' 238 - ) 239 - ) 240 - ). 241 - phutil_tag( 242 - 'div', 243 - array( 244 - 'class' => 'widgets-body', 245 - 'id' => 'widgets-files', 246 - 'style' => 'display: none;' 247 - ), 248 - $this->renderFilesWidgetPaneContent() 249 - ). 250 - phutil_tag( 251 - 'div', 164 + $scrollbutton = javelin_tag( 165 + 'a', 252 166 array( 253 - 'class' => 'widgets-body', 254 - 'id' => 'widgets-tasks', 167 + 'href' => '#', 168 + 'mustcapture' => true, 169 + 'sigil' => 'show-older-messages', 170 + 'class' => 'conpherence-show-older-messages', 255 171 ), 256 - $this->renderTaskWidgetPaneContent() 257 - ). 258 - phutil_tag( 259 - 'div', 260 - array( 261 - 'class' => 'widgets-body', 262 - 'id' => 'widgets-calendar', 263 - 'style' => 'display: none;' 264 - ), 265 - $this->renderCalendarWidgetPaneContent() 266 - ); 267 - 268 - return array('widgets' => $widgets); 269 - } 270 - 271 - private function renderFilesWidgetPaneContent() { 272 - $conpherence = $this->getConpherence(); 273 - $widget_data = $conpherence->getWidgetData(); 274 - $files = $widget_data['files']; 275 - 276 - $table_data = array(); 277 - foreach ($files as $file) { 278 - $thumb = $file->getThumb60x45URI(); 279 - $table_data[] = array( 280 - phutil_tag( 281 - 'img', 282 - array( 283 - 'src' => $thumb 284 - ), 285 - ''), 286 - $file->getName(), 287 - ); 288 - } 289 - $header = id(new PhabricatorHeaderView()) 290 - ->setHeader(pht('Attached Files')); 291 - $table = id(new AphrontTableView($table_data)) 292 - ->setNoDataString(pht('No files attached to conpherence.')) 293 - ->setHeaders(array('', pht('Name'))) 294 - ->setColumnClasses(array('', 'wide')); 295 - return hsprintf('%s%s', $header->render(), $table->render()); 296 - } 297 - 298 - private function renderTaskWidgetPaneContent() { 299 - $conpherence = $this->getConpherence(); 300 - $widget_data = $conpherence->getWidgetData(); 301 - $tasks = $widget_data['tasks']; 302 - $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); 303 - $handles = $conpherence->getHandles(); 304 - $content = array(); 305 - foreach ($tasks as $owner_phid => $actual_tasks) { 306 - $handle = $handles[$owner_phid]; 307 - $content[] = id(new PhabricatorHeaderView()) 308 - ->setHeader($handle->getName()) 309 - ->render(); 310 - $actual_tasks = msort($actual_tasks, 'getPriority'); 311 - $actual_tasks = array_reverse($actual_tasks); 312 - $data = array(); 313 - foreach ($actual_tasks as $task) { 314 - $data[] = array( 315 - idx($priority_map, $task->getPriority(), pht('???')), 316 - phutil_tag( 317 - 'a', 318 - array( 319 - 'href' => '/T'.$task->getID() 320 - ), 321 - $task->getTitle() 322 - ) 323 - ); 324 - } 325 - $table = id(new AphrontTableView($data)) 326 - ->setNoDataString(pht('No open tasks.')) 327 - ->setHeaders(array(pht('Pri'), pht('Title'))) 328 - ->setColumnClasses(array('', 'wide')); 329 - $content[] = $table->render(); 330 - } 331 - return phutil_implode_html('', $content); 332 - } 333 - 334 - private function renderCalendarWidgetPaneContent() { 335 - $user = $this->getRequest()->getUser(); 336 - 337 - $conpherence = $this->getConpherence(); 338 - $widget_data = $conpherence->getWidgetData(); 339 - $statuses = $widget_data['statuses']; 340 - $handles = $conpherence->getHandles(); 341 - $content = array(); 342 - $timestamps = $this->getCalendarWidgetWeekTimestamps(); 343 - $one_day = 24 * 60 * 60; 344 - foreach ($timestamps as $time => $day) { 345 - // build a header for the new day 346 - $content[] = id(new PhabricatorHeaderView()) 347 - ->setHeader($day->format('l')) 348 - ->render(); 349 - 350 - $day->setTime(0, 0, 0); 351 - $epoch_start = $day->format('U'); 352 - $day->modify('+1 day'); 353 - $epoch_end = $day->format('U'); 354 - 355 - // keep looking through statuses where we last left off 356 - foreach ($statuses as $status) { 357 - if ($status->getDateFrom() >= $epoch_end) { 358 - // This list is sorted, so we can stop looking. 359 - break; 360 - } 361 - if ($status->getDateFrom() < $epoch_end && 362 - $status->getDateTo() > $epoch_start) { 363 - $timespan = $status->getDateTo() - $status->getDateFrom(); 364 - if ($timespan > $one_day) { 365 - $time_str = 'm/d'; 366 - } else { 367 - $time_str = 'h:i A'; 368 - } 369 - $epoch_range = phabricator_format_local_time( 370 - $status->getDateFrom(), 371 - $user, 372 - $time_str 373 - ) . ' - ' . phabricator_format_local_time( 374 - $status->getDateTo(), 375 - $user, 376 - $time_str 377 - ); 172 + pht('Show Older Messages')); 378 173 379 - $content[] = phutil_tag( 380 - 'div', 381 - array( 382 - 'class' => 'user-status '.$status->getTextStatus(), 383 - ), 384 - array( 385 - phutil_tag( 386 - 'div', 387 - array( 388 - 'class' => 'epoch-range' 389 - ), 390 - $epoch_range 391 - ), 392 - phutil_tag( 393 - 'div', 394 - array( 395 - 'class' => 'icon', 396 - ), 397 - '' 398 - ), 399 - phutil_tag( 400 - 'div', 401 - array( 402 - 'class' => 'description' 403 - ), 404 - $status->getTerseSummary($user) 405 - ), 406 - phutil_tag( 407 - 'div', 408 - array( 409 - 'class' => 'participant' 410 - ), 411 - $handles[$status->getUserPHID()]->getName() 412 - ) 413 - ) 414 - ); 415 - } 416 - } 417 - } 174 + return array( 175 + 'messages' => $scrollbutton.$transactions, 176 + 'form' => $form 177 + ); 418 178 419 - return phutil_implode_html('', $content); 420 - } 421 - 422 - private function getCalendarWidgetWeekTimestamps() { 423 - $user = $this->getRequest()->getUser(); 424 - $timezone = new DateTimeZone($user->getTimezoneIdentifier()); 425 - 426 - $timestamps = array(); 427 - for ($day = 0; $day < 7; $day++) { 428 - $timestamps[] = new DateTime( 429 - sprintf('today +%d days', $day), 430 - $timezone 431 - ); 432 - } 433 - 434 - return $timestamps; 435 179 } 436 180 437 181 }
+312
src/applications/conpherence/controller/ConpherenceWidgetController.php
··· 1 + <?php 2 + 3 + /** 4 + * @group conpherence 5 + */ 6 + final class ConpherenceWidgetController extends 7 + ConpherenceController { 8 + 9 + private $conpherenceID; 10 + private $conpherence; 11 + 12 + public function setConpherence(ConpherenceThread $conpherence) { 13 + $this->conpherence = $conpherence; 14 + return $this; 15 + } 16 + public function getConpherence() { 17 + return $this->conpherence; 18 + } 19 + 20 + public function setConpherenceID($conpherence_id) { 21 + $this->conpherenceID = $conpherence_id; 22 + return $this; 23 + } 24 + public function getConpherenceID() { 25 + return $this->conpherenceID; 26 + } 27 + 28 + public function willProcessRequest(array $data) { 29 + $this->setConpherenceID(idx($data, 'id')); 30 + } 31 + 32 + public function processRequest() { 33 + $request = $this->getRequest(); 34 + $user = $request->getUser(); 35 + 36 + $conpherence_id = $this->getConpherenceID(); 37 + if (!$conpherence_id) { 38 + return new Aphront404Response(); 39 + } 40 + $conpherence = id(new ConpherenceThreadQuery()) 41 + ->setViewer($user) 42 + ->withIDs(array($conpherence_id)) 43 + ->needWidgetData(true) 44 + ->executeOne(); 45 + $this->setConpherence($conpherence); 46 + 47 + $widgets = $this->renderWidgetPaneContent(); 48 + $content = $widgets; 49 + return id(new AphrontAjaxResponse())->setContent($content); 50 + } 51 + 52 + private function renderWidgetPaneContent() { 53 + require_celerity_resource('conpherence-widget-pane-css'); 54 + require_celerity_resource('sprite-conpher-css'); 55 + Javelin::initBehavior( 56 + 'conpherence-widget-pane', 57 + array( 58 + 'widgetRegistery' => array( 59 + 'widgets-files' => 1, 60 + 'widgets-tasks' => 1, 61 + 'widgets-calendar' => 1, 62 + ) 63 + ) 64 + ); 65 + 66 + $conpherence = $this->getConpherence(); 67 + 68 + $widgets = phutil_tag( 69 + 'div', 70 + array( 71 + 'class' => 'widgets-header' 72 + ), 73 + array( 74 + javelin_tag( 75 + 'a', 76 + array( 77 + 'sigil' => 'conpherence-change-widget', 78 + 'meta' => array( 79 + 'widget' => 'widgets-files', 80 + 'toggleClass' => 'conpher_files_on' 81 + ), 82 + 'id' => 'widgets-files-toggle', 83 + 'class' => 'sprite-conpher conpher_files_off first-icon' 84 + ), 85 + '' 86 + ), 87 + javelin_tag( 88 + 'a', 89 + array( 90 + 'sigil' => 'conpherence-change-widget', 91 + 'meta' => array( 92 + 'widget' => 'widgets-tasks', 93 + 'toggleClass' => 'conpher_list_on' 94 + ), 95 + 'id' => 'widgets-tasks-toggle', 96 + 'class' => 'sprite-conpher conpher_list_off conpher_list_on', 97 + ), 98 + '' 99 + ), 100 + javelin_tag( 101 + 'a', 102 + array( 103 + 'sigil' => 'conpherence-change-widget', 104 + 'meta' => array( 105 + 'widget' => 'widgets-calendar', 106 + 'toggleClass' => 'conpher_calendar_on' 107 + ), 108 + 'id' => 'widgets-calendar-toggle', 109 + 'class' => 'sprite-conpher conpher_calendar_off', 110 + ), 111 + '' 112 + ) 113 + ) 114 + ). 115 + phutil_tag( 116 + 'div', 117 + array( 118 + 'class' => 'widgets-body', 119 + 'id' => 'widgets-files', 120 + 'style' => 'display: none;' 121 + ), 122 + $this->renderFilesWidgetPaneContent() 123 + ). 124 + phutil_tag( 125 + 'div', 126 + array( 127 + 'class' => 'widgets-body', 128 + 'id' => 'widgets-tasks', 129 + ), 130 + $this->renderTaskWidgetPaneContent() 131 + ). 132 + phutil_tag( 133 + 'div', 134 + array( 135 + 'class' => 'widgets-body', 136 + 'id' => 'widgets-calendar', 137 + 'style' => 'display: none;' 138 + ), 139 + $this->renderCalendarWidgetPaneContent() 140 + ); 141 + 142 + return array('widgets' => $widgets); 143 + } 144 + 145 + private function renderFilesWidgetPaneContent() { 146 + $conpherence = $this->getConpherence(); 147 + $widget_data = $conpherence->getWidgetData(); 148 + $files = $widget_data['files']; 149 + 150 + $table_data = array(); 151 + foreach ($files as $file) { 152 + $thumb = $file->getThumb60x45URI(); 153 + $table_data[] = array( 154 + phutil_tag( 155 + 'img', 156 + array( 157 + 'src' => $thumb 158 + ), 159 + '' 160 + ), 161 + $file->getName() 162 + ); 163 + } 164 + $header = id(new PhabricatorHeaderView()) 165 + ->setHeader(pht('Attached Files')); 166 + $table = id(new AphrontTableView($table_data)) 167 + ->setNoDataString(pht('No files attached to conpherence.')) 168 + ->setHeaders(array('', pht('Name'))) 169 + ->setColumnClasses(array('', 'wide')); 170 + return new PhutilSafeHTML($header->render() . $table->render()); 171 + } 172 + 173 + private function renderTaskWidgetPaneContent() { 174 + $conpherence = $this->getConpherence(); 175 + $widget_data = $conpherence->getWidgetData(); 176 + $tasks = $widget_data['tasks']; 177 + $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); 178 + $handles = $conpherence->getHandles(); 179 + $content = array(); 180 + foreach ($tasks as $owner_phid => $actual_tasks) { 181 + $handle = $handles[$owner_phid]; 182 + $content[] = id(new PhabricatorHeaderView()) 183 + ->setHeader($handle->getName()) 184 + ->render(); 185 + $actual_tasks = msort($actual_tasks, 'getPriority'); 186 + $actual_tasks = array_reverse($actual_tasks); 187 + $data = array(); 188 + foreach ($actual_tasks as $task) { 189 + $data[] = array( 190 + idx($priority_map, $task->getPriority(), pht('???')), 191 + phutil_tag( 192 + 'a', 193 + array( 194 + 'href' => '/T'.$task->getID() 195 + ), 196 + $task->getTitle() 197 + ) 198 + ); 199 + } 200 + $table = id(new AphrontTableView($data)) 201 + ->setNoDataString(pht('No open tasks.')) 202 + ->setHeaders(array(pht('Pri'), pht('Title'))) 203 + ->setColumnClasses(array('', 'wide')); 204 + $content[] = $table->render(); 205 + } 206 + return new PhutilSafeHTML(implode('', $content)); 207 + } 208 + 209 + private function renderCalendarWidgetPaneContent() { 210 + $user = $this->getRequest()->getUser(); 211 + 212 + $conpherence = $this->getConpherence(); 213 + $widget_data = $conpherence->getWidgetData(); 214 + $statuses = $widget_data['statuses']; 215 + $handles = $conpherence->getHandles(); 216 + $content = array(); 217 + $timestamps = $this->getCalendarWidgetWeekTimestamps(); 218 + $one_day = 24 * 60 * 60; 219 + foreach ($timestamps as $time => $day) { 220 + // build a header for the new day 221 + $content[] = id(new PhabricatorHeaderView()) 222 + ->setHeader($day->format('l')) 223 + ->render(); 224 + 225 + $day->setTime(0, 0, 0); 226 + $epoch_start = $day->format('U'); 227 + $day->modify('+1 day'); 228 + $epoch_end = $day->format('U'); 229 + 230 + // keep looking through statuses where we last left off 231 + foreach ($statuses as $status) { 232 + if ($status->getDateFrom() >= $epoch_end) { 233 + // This list is sorted, so we can stop looking. 234 + break; 235 + } 236 + if ($status->getDateFrom() < $epoch_end && 237 + $status->getDateTo() > $epoch_start) { 238 + $timespan = $status->getDateTo() - $status->getDateFrom(); 239 + if ($timespan > $one_day) { 240 + $time_str = 'm/d'; 241 + } else { 242 + $time_str = 'h:i A'; 243 + } 244 + $epoch_range = phabricator_format_local_time( 245 + $status->getDateFrom(), 246 + $user, 247 + $time_str 248 + ) . ' - ' . phabricator_format_local_time( 249 + $status->getDateTo(), 250 + $user, 251 + $time_str 252 + ); 253 + 254 + $content[] = phutil_tag( 255 + 'div', 256 + array( 257 + 'class' => 'user-status '.$status->getTextStatus(), 258 + ), 259 + array( 260 + phutil_tag( 261 + 'div', 262 + array( 263 + 'class' => 'epoch-range' 264 + ), 265 + $epoch_range 266 + ), 267 + phutil_tag( 268 + 'div', 269 + array( 270 + 'class' => 'icon', 271 + ), 272 + '' 273 + ), 274 + phutil_tag( 275 + 'div', 276 + array( 277 + 'class' => 'description' 278 + ), 279 + $status->getTerseSummary($user) 280 + ), 281 + phutil_tag( 282 + 'div', 283 + array( 284 + 'class' => 'participant' 285 + ), 286 + $handles[$status->getUserPHID()]->getName() 287 + ) 288 + ) 289 + ); 290 + } 291 + } 292 + } 293 + 294 + return new PhutilSafeHTML(implode('', $content)); 295 + } 296 + 297 + private function getCalendarWidgetWeekTimestamps() { 298 + $user = $this->getRequest()->getUser(); 299 + $timezone = new DateTimeZone($user->getTimezoneIdentifier()); 300 + 301 + $timestamps = array(); 302 + for ($day = 0; $day < 7; $day++) { 303 + $timestamps[] = new DateTime( 304 + sprintf('today +%d days', $day), 305 + $timezone 306 + ); 307 + } 308 + 309 + return $timestamps; 310 + } 311 + 312 + }
+17
src/applications/conpherence/storage/ConpherenceThread.php
··· 117 117 return $this->transactions; 118 118 } 119 119 120 + public function getTransactionsFrom($begin = 0, $amount = null) { 121 + $length = count($this->transactions); 122 + if ($amount === null) { 123 + $amount === $length; 124 + } 125 + if ($this->transactions === null) { 126 + throw new Exception( 127 + 'You must attachTransactions first!' 128 + ); 129 + } 130 + return array_slice( 131 + $this->transactions, 132 + $length - $begin - $amount, 133 + $amount 134 + ); 135 + } 136 + 120 137 public function attachFilePHIDs(array $file_phids) { 121 138 $this->filePHIDs = $file_phids; 122 139 return $this;
+8
webroot/rsrc/css/application/conpherence/message-pane.css
··· 10 10 height: 100%; 11 11 margin: 0px 320px 0px 0px; 12 12 } 13 + .conpherence-show-older-messages { 14 + display: block; 15 + background: #e0e3ec; 16 + margin: 10px; 17 + text-align: center; 18 + padding: 10px; 19 + color: #18559D; 20 + } 13 21 14 22 .conpherence-message-pane .conpherence-messages { 15 23 position: fixed;
+20 -3
webroot/rsrc/js/application/conpherence/behavior-menu.js
··· 10 10 11 11 JX.behavior('conpherence-menu', function(config) { 12 12 13 + function onwidgetresponse(context, response) { 14 + var widgets = JX.$H(response.widgets); 15 + var widgetsRoot = JX.$(config.widgets_pane); 16 + JX.DOM.setContent(widgetsRoot, widgets); 17 + } 18 + 13 19 function onresponse(context, response) { 14 20 var header = JX.$H(response.header); 15 21 var messages = JX.$H(response.messages); 16 22 var form = JX.$H(response.form); 17 - var widgets = JX.$H(response.widgets); 18 23 var headerRoot = JX.$(config.header); 19 24 var messagesRoot = JX.$(config.messages); 20 25 var formRoot = JX.$(config.form_pane); ··· 24 29 JX.DOM.setContent(messagesRoot, messages); 25 30 messagesRoot.scrollTop = messagesRoot.scrollHeight; 26 31 JX.DOM.setContent(formRoot, form); 27 - JX.DOM.setContent(widgetsRoot, widgets); 28 32 29 33 var conpherences = JX.DOM.scry( 30 34 menuRoot, ··· 92 96 93 97 var selected = e.getData().selected; 94 98 var data = JX.Stratcom.getData(selected); 95 - 96 99 var uri = config.base_uri + 'view/' + data.id + '/'; 100 + var widget_uri = config.base_uri + 'widget/' + data.id + '/'; 97 101 new JX.Workflow(uri, {}) 98 102 .setHandler(JX.bind(null, onresponse, selected)) 99 103 .start(); 104 + new JX.Workflow(widget_uri, {}) 105 + .setHandler(JX.bind(null, onwidgetresponse, selected)) 106 + .start(); 100 107 } 101 108 ); 109 + 110 + JX.Stratcom.listen('click', 'show-older-messages', function(e) { 111 + e.kill(); 112 + console.log(document.URL); 113 + new JX.Request('/conpherence/view/1/', function(r) { 114 + console.log('100'); 115 + }) 116 + .setData({offset: 100}) // get the next page 117 + .send(); 118 + }); 102 119 103 120 });