Page MenuHomePhabricator

D8317.diff
No OneTemporary

D8317.diff

Index: resources/celerity/map.php
===================================================================
--- resources/celerity/map.php
+++ resources/celerity/map.php
@@ -94,7 +94,7 @@
'rsrc/css/application/ponder/feed.css' => 'e62615b6',
'rsrc/css/application/ponder/post.css' => 'ebab8a70',
'rsrc/css/application/ponder/vote.css' => '8ed6ed8b',
- 'rsrc/css/application/profile/profile-view.css' => '3a7e04ca',
+ 'rsrc/css/application/profile/profile-view.css' => '9bdb9804',
'rsrc/css/application/projects/phabricator-object-list-view.css' => '1a1ea560',
'rsrc/css/application/projects/project-tag.css' => '095c9404',
'rsrc/css/application/releeph/releeph-branch.css' => 'b8821d2d',
@@ -123,9 +123,12 @@
'rsrc/css/layout/phabricator-hovercard-view.css' => '67c12b16',
'rsrc/css/layout/phabricator-side-menu-view.css' => '503699d0',
'rsrc/css/layout/phabricator-source-code-view.css' => '62a99814',
- 'rsrc/css/phui/phui-box.css' => '1a82a4ae',
+ 'rsrc/css/phui/calendar/phui-calendar-day.css' => 'de035c8a',
+ 'rsrc/css/phui/calendar/phui-calendar-list.css' => 'c1d0ca59',
+ 'rsrc/css/phui/calendar/phui-calendar-month.css' => '5e762971',
+ 'rsrc/css/phui/calendar/phui-calendar.css' => '5e1ad989',
+ 'rsrc/css/phui/phui-box.css' => 'a36cf3a5',
'rsrc/css/phui/phui-button.css' => '8784a966',
- 'rsrc/css/phui/phui-calendar-month.css' => '3474d15a',
'rsrc/css/phui/phui-document.css' => '143b2ac8',
'rsrc/css/phui/phui-feed-story.css' => '3a59c2cf',
'rsrc/css/phui/phui-form-view.css' => '0efd3326',
@@ -134,7 +137,7 @@
'rsrc/css/phui/phui-icon.css' => 'fcb145a7',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-list.css' => '2edb76cf',
- 'rsrc/css/phui/phui-object-box.css' => '95767d08',
+ 'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec',
'rsrc/css/phui/phui-object-item-list-view.css' => 'eb579d6c',
'rsrc/css/phui/phui-pinboard-view.css' => '4b346c2a',
'rsrc/css/phui/phui-property-list-view.css' => 'dbf53b12',
@@ -702,7 +705,7 @@
'phabricator-object-selector-css' => '029a133d',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '0326e5d0',
- 'phabricator-profile-css' => '3a7e04ca',
+ 'phabricator-profile-css' => '9bdb9804',
'phabricator-project-tag-css' => '095c9404',
'phabricator-remarkup-css' => 'ca7f2265',
'phabricator-search-results-css' => 'f240504c',
@@ -735,9 +738,12 @@
'phortune-credit-card-form-css' => 'b25b4beb',
'phrequent-css' => 'ffc185ad',
'phriction-document-css' => 'b0309d8e',
- 'phui-box-css' => '1a82a4ae',
+ 'phui-box-css' => 'a36cf3a5',
'phui-button-css' => '8784a966',
- 'phui-calendar-month-css' => '3474d15a',
+ 'phui-calendar-css' => '5e1ad989',
+ 'phui-calendar-day-css' => 'de035c8a',
+ 'phui-calendar-list-css' => 'c1d0ca59',
+ 'phui-calendar-month-css' => '5e762971',
'phui-document-view-css' => '143b2ac8',
'phui-feed-story-css' => '3a59c2cf',
'phui-form-css' => 'b78ec020',
@@ -746,7 +752,7 @@
'phui-icon-view-css' => 'fcb145a7',
'phui-info-panel-css' => '27ea50a1',
'phui-list-view-css' => '2edb76cf',
- 'phui-object-box-css' => '95767d08',
+ 'phui-object-box-css' => 'ce92d8ec',
'phui-object-item-list-view-css' => 'eb579d6c',
'phui-pinboard-view-css' => '4b346c2a',
'phui-property-list-view-css' => 'dbf53b12',
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -93,6 +93,8 @@
'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
'AuditActionMenuEventListener' => 'applications/audit/events/AuditActionMenuEventListener.php',
'BuildStepImplementation' => 'applications/harbormaster/step/BuildStepImplementation.php',
+ 'CalendarColors' => 'applications/calendar/constants/CalendarColors.php',
+ 'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php',
'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php',
'CelerityManagementMapWorkflow' => 'infrastructure/celerity/management/CelerityManagementMapWorkflow.php',
'CelerityManagementWorkflow' => 'infrastructure/celerity/management/CelerityManagementWorkflow.php',
@@ -1000,7 +1002,9 @@
'PHUIButtonBarView' => 'view/phui/PHUIButtonBarView.php',
'PHUIButtonExample' => 'applications/uiexample/examples/PHUIButtonExample.php',
'PHUIButtonView' => 'view/phui/PHUIButtonView.php',
- 'PHUICalendarMonthView' => 'applications/calendar/view/PHUICalendarMonthView.php',
+ 'PHUICalendarListView' => 'view/phui/calendar/PHUICalendarListView.php',
+ 'PHUICalendarMonthView' => 'view/phui/calendar/PHUICalendarMonthView.php',
+ 'PHUICalendarWidgetView' => 'view/phui/calendar/PHUICalendarWidgetView.php',
'PHUIColorPalletteExample' => 'applications/uiexample/examples/PHUIColorPalletteExample.php',
'PHUIDocumentExample' => 'applications/uiexample/examples/PHUIDocumentExample.php',
'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php',
@@ -1291,7 +1295,6 @@
'PhabricatorCalendarEventEditController' => 'applications/calendar/controller/PhabricatorCalendarEventEditController.php',
'PhabricatorCalendarEventInvalidEpochException' => 'applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php',
'PhabricatorCalendarEventListController' => 'applications/calendar/controller/PhabricatorCalendarEventListController.php',
- 'PhabricatorCalendarEventOverlapException' => 'applications/calendar/exception/PhabricatorCalendarEventOverlapException.php',
'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
'PhabricatorCalendarEventSearchEngine' => 'applications/calendar/query/PhabricatorCalendarEventSearchEngine.php',
'PhabricatorCalendarEventViewController' => 'applications/calendar/controller/PhabricatorCalendarEventViewController.php',
@@ -1800,6 +1803,7 @@
'PhabricatorPasteTransactionQuery' => 'applications/paste/query/PhabricatorPasteTransactionQuery.php',
'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php',
'PhabricatorPeopleApproveController' => 'applications/people/controller/PhabricatorPeopleApproveController.php',
+ 'PhabricatorPeopleCalendarController' => 'applications/people/controller/PhabricatorPeopleCalendarController.php',
'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php',
'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
'PhabricatorPeopleEditController' => 'applications/people/controller/PhabricatorPeopleEditController.php',
@@ -2652,6 +2656,7 @@
),
'AphrontWebpageResponse' => 'AphrontHTMLResponse',
'AuditActionMenuEventListener' => 'PhabricatorEventListener',
+ 'CalendarColors' => 'CalendarConstants',
'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow',
'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow',
'CelerityPhabricatorResourceController' => 'CelerityResourceController',
@@ -3666,7 +3671,9 @@
'PHUIButtonBarView' => 'AphrontTagView',
'PHUIButtonExample' => 'PhabricatorUIExample',
'PHUIButtonView' => 'AphrontTagView',
+ 'PHUICalendarListView' => 'AphrontTagView',
'PHUICalendarMonthView' => 'AphrontView',
+ 'PHUICalendarWidgetView' => 'AphrontTagView',
'PHUIColorPalletteExample' => 'PhabricatorUIExample',
'PHUIDocumentExample' => 'PhabricatorUIExample',
'PHUIDocumentView' => 'AphrontTagView',
@@ -3987,7 +3994,6 @@
0 => 'PhabricatorCalendarController',
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
),
- 'PhabricatorCalendarEventOverlapException' => 'Exception',
'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarEventSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorCalendarEventViewController' => 'PhabricatorCalendarController',
@@ -4563,6 +4569,7 @@
'PhabricatorPasteTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleApproveController' => 'PhabricatorPeopleController',
+ 'PhabricatorPeopleCalendarController' => 'PhabricatorPeopleController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
Index: src/applications/calendar/constants/CalendarColors.php
===================================================================
--- /dev/null
+++ src/applications/calendar/constants/CalendarColors.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @group calendar
+ */
+final class CalendarColors extends CalendarConstants {
+
+ const COLOR_RED = 'red';
+ const COLOR_ORANGE = 'orange';
+ const COLOR_YELLOW = 'yellow';
+ const COLOR_GREEN = 'green';
+ const COLOR_BLUE = 'blue';
+ const COLOR_SKY = 'sky';
+ const COLOR_INDIGO = 'indigo';
+ const COLOR_VIOLET = 'violet';
+
+ public static function getColors() {
+ return array(
+ self::COLOR_SKY,
+ self::COLOR_GREEN,
+ self::COLOR_VIOLET,
+ self::COLOR_ORANGE,
+ self::COLOR_BLUE,
+ self::COLOR_INDIGO,
+ self::COLOR_RED,
+ self::COLOR_YELLOW,
+ );
+ }
+
+}
Index: src/applications/calendar/constants/CalendarConstants.php
===================================================================
--- /dev/null
+++ src/applications/calendar/constants/CalendarConstants.php
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * @group calendar
+ */
+abstract class CalendarConstants {
+
+}
Index: src/applications/calendar/controller/PhabricatorCalendarBrowseController.php
===================================================================
--- src/applications/calendar/controller/PhabricatorCalendarBrowseController.php
+++ src/applications/calendar/controller/PhabricatorCalendarBrowseController.php
@@ -39,6 +39,24 @@
$phids = mpull($statuses, 'getUserPHID');
$handles = $this->loadViewerHandles($phids);
+ /* Assign Colors */
+ $unique = array_unique($phids);
+ $allblue = false;
+ $calcolors = CalendarColors::getColors();
+ if (count($unique) > count($calcolors)) {
+ $allblue = true;
+ }
+ $i = 0;
+ $eventcolor = array();
+ foreach ($unique as $phid) {
+ if ($allblue) {
+ $eventcolor[$phid] = CalendarColors::COLOR_SKY;
+ } else {
+ $eventcolor[$phid] = $calcolors[$i];
+ }
+ $i++;
+ }
+
foreach ($statuses as $status) {
$event = new AphrontCalendarEventView();
$event->setEpochRange($status->getDateFrom(), $status->getDateTo());
@@ -46,14 +64,10 @@
$name_text = $handles[$status->getUserPHID()]->getName();
$status_text = $status->getHumanStatus();
$event->setUserPHID($status->getUserPHID());
- $event->setName("{$name_text} ({$status_text})");
- $details = '';
- if ($status->getDescription()) {
- $details = "\n\n".rtrim($status->getDescription());
- }
- $event->setDescription(
- $status->getTerseSummary($user).$details);
+ $event->setDescription(pht('%s (%s)', $name_text, $status_text));
+ $event->setName($status_text);
$event->setEventID($status->getID());
+ $event->setColor($eventcolor[$status->getUserPHID()]);
$month_view->addEvent($event);
}
Index: src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
===================================================================
--- src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
+++ src/applications/calendar/controller/PhabricatorCalendarEventEditController.php
@@ -73,9 +73,6 @@
->save();
} catch (PhabricatorCalendarEventInvalidEpochException $e) {
$errors[] = pht('Start must be before end.');
- } catch (PhabricatorCalendarEventOverlapException $e) {
- $errors[] = pht('There is already a status within the specified '.
- 'timeframe. Edit or delete this existing status.');
}
if (!$errors) {
Index: src/applications/calendar/exception/PhabricatorCalendarEventOverlapException.php
===================================================================
--- src/applications/calendar/exception/PhabricatorCalendarEventOverlapException.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-
-final class PhabricatorCalendarEventOverlapException extends Exception {
-}
Index: src/applications/calendar/storage/PhabricatorCalendarEvent.php
===================================================================
--- src/applications/calendar/storage/PhabricatorCalendarEvent.php
+++ src/applications/calendar/storage/PhabricatorCalendarEvent.php
@@ -73,7 +73,7 @@
/**
* Validates data and throws exceptions for non-sensical status
- * windows and attempts to create an overlapping status.
+ * windows
*/
public function save() {
@@ -81,28 +81,7 @@
throw new PhabricatorCalendarEventInvalidEpochException();
}
- $this->openTransaction();
- $this->beginWriteLocking();
-
- if ($this->shouldInsertWhenSaved()) {
-
- $overlap = $this->loadAllWhere(
- 'userPHID = %s AND dateFrom < %d AND dateTo > %d',
- $this->getUserPHID(),
- $this->getDateTo(),
- $this->getDateFrom());
-
- if ($overlap) {
- $this->endWriteLocking();
- $this->killTransaction();
- throw new PhabricatorCalendarEventOverlapException();
- }
- }
-
- parent::save();
-
- $this->endWriteLocking();
- return $this->saveTransaction();
+ return parent::save();
}
Index: src/applications/calendar/view/AphrontCalendarEventView.php
===================================================================
--- src/applications/calendar/view/AphrontCalendarEventView.php
+++ src/applications/calendar/view/AphrontCalendarEventView.php
@@ -8,6 +8,7 @@
private $epochEnd;
private $description;
private $eventID;
+ private $color;
public function setEventID($event_id) {
$this->eventID = $event_id;
@@ -58,6 +59,18 @@
return $this->description;
}
+ public function setColor($color) {
+ $this->color = $color;
+ return $this;
+ }
+ public function getColor() {
+ if ($this->color) {
+ return $this->color;
+ } else {
+ return CalendarColors::COLOR_SKY;
+ }
+ }
+
public function render() {
throw new Exception("Events are only rendered indirectly.");
}
Index: src/applications/people/application/PhabricatorApplicationPeople.php
===================================================================
--- src/applications/people/application/PhabricatorApplicationPeople.php
+++ src/applications/people/application/PhabricatorApplicationPeople.php
@@ -3,7 +3,7 @@
final class PhabricatorApplicationPeople extends PhabricatorApplication {
public function getShortDescription() {
- return 'User Accounts';
+ return pht('User Accounts');
}
public function getBaseURI() {
@@ -53,6 +53,8 @@
),
'/p/(?P<username>[\w._-]+)/'
=> 'PhabricatorPeopleProfileController',
+ '/p/(?P<username>[\w._-]+)/calendar/'
+ => 'PhabricatorPeopleCalendarController',
);
}
Index: src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php
===================================================================
--- src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php
+++ src/applications/people/conduit/ConduitAPI_user_addstatus_Method.php
@@ -51,8 +51,6 @@
->save();
} catch (PhabricatorCalendarEventInvalidEpochException $e) {
throw new ConduitException('ERR-BAD-EPOCH');
- } catch (PhabricatorCalendarEventOverlapException $e) {
- throw new ConduitException('ERR-OVERLAP');
}
}
Index: src/applications/people/controller/PhabricatorPeopleCalendarController.php
===================================================================
--- src/applications/people/controller/PhabricatorPeopleCalendarController.php
+++ src/applications/people/controller/PhabricatorPeopleCalendarController.php
@@ -1,12 +1,34 @@
<?php
-final class PhabricatorCalendarBrowseController
- extends PhabricatorCalendarController {
+final class PhabricatorPeopleCalendarController
+ extends PhabricatorPeopleController {
+
+ private $username;
+
+ public function shouldRequireAdmin() {
+ return false;
+ }
+
+ public function willProcessRequest(array $data) {
+ $this->username = idx($data, 'username');
+ }
public function processRequest() {
+ $viewer = $this->getRequest()->getUser();
+ $user = id(new PhabricatorPeopleQuery())
+ ->setViewer($viewer)
+ ->withUsernames(array($this->username))
+ ->needProfileImage(true)
+ ->executeOne();
+
+ if (!$user) {
+ return new Aphront404Response();
+ }
+
+ $picture = $user->loadProfileImageURI();
+
$now = time();
$request = $this->getRequest();
- $user = $request->getUser();
$year_d = phabricator_format_local_time($now, $user, 'Y');
$year = $request->getInt('year', $year_d);
$month_d = phabricator_format_local_time($now, $user, 'm');
@@ -21,6 +43,7 @@
$statuses = id(new PhabricatorCalendarEventQuery())
->setViewer($user)
+ ->withInvitedPHIDs(array($user->getPHID()))
->withDateRange(
strtotime("{$year}-{$month}-01"),
strtotime("{$year}-{$month}-01 next month"))
@@ -35,6 +58,7 @@
$month_view->setBrowseURI($request->getRequestURI());
$month_view->setUser($user);
$month_view->setHolidays($holidays);
+ $month_view->setImage($picture);
$phids = mpull($statuses, 'getUserPHID');
$handles = $this->loadViewerHandles($phids);
@@ -42,61 +66,27 @@
foreach ($statuses as $status) {
$event = new AphrontCalendarEventView();
$event->setEpochRange($status->getDateFrom(), $status->getDateTo());
-
- $name_text = $handles[$status->getUserPHID()]->getName();
- $status_text = $status->getHumanStatus();
$event->setUserPHID($status->getUserPHID());
- $event->setName("{$name_text} ({$status_text})");
- $details = '';
- if ($status->getDescription()) {
- $details = "\n\n".rtrim($status->getDescription());
- }
- $event->setDescription(
- $status->getTerseSummary($user).$details);
+ $event->setName($status->getHumanStatus());
+ $event->setDescription($status->getDescription());
$event->setEventID($status->getID());
$month_view->addEvent($event);
}
$date = new DateTime("{$year}-{$month}-01");
$crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(
+ $user->getUsername(),
+ '/p/'.$user->getUsername().'/');
$crumbs->addTextCrumb($date->format('F Y'));
- $nav = $this->buildSideNavView();
- $nav->selectFilter('/');
- $nav->appendChild(
- array(
- $crumbs,
- $this->getNoticeView(),
- $month_view,
- ));
-
return $this->buildApplicationPage(
- $nav,
+ array(
+ $crumbs,
+ $month_view),
array(
'title' => pht('Calendar'),
'device' => true,
));
}
-
- private function getNoticeView() {
- $request = $this->getRequest();
- $view = null;
-
- if ($request->getExists('created')) {
- $view = id(new AphrontErrorView())
- ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
- ->setTitle(pht('Successfully created your status.'));
- } else if ($request->getExists('updated')) {
- $view = id(new AphrontErrorView())
- ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
- ->setTitle(pht('Successfully updated your status.'));
- } else if ($request->getExists('deleted')) {
- $view = id(new AphrontErrorView())
- ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
- ->setTitle(pht('Successfully deleted your status.'));
- }
-
- return $view;
- }
-
}
Index: src/applications/people/controller/PhabricatorPeopleProfileController.php
===================================================================
--- src/applications/people/controller/PhabricatorPeopleProfileController.php
+++ src/applications/people/controller/PhabricatorPeopleProfileController.php
@@ -73,6 +73,16 @@
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($user->getUsername());
$feed = $this->renderUserFeed($user);
+ $calendar = $this->renderUserCalendar($user);
+ $activity = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'profile-activity-view grouped'
+ ),
+ array(
+ $calendar,
+ $feed
+ ));
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
@@ -82,7 +92,7 @@
array(
$crumbs,
$object_box,
- $feed,
+ $activity,
),
array(
'title' => $user->getUsername(),
@@ -129,4 +139,72 @@
'profile-feed',
$view->render());
}
+
+ private function renderUserCalendar(PhabricatorUser $user) {
+ $now = time();
+ $year = phabricator_format_local_time($now, $user, 'Y');
+ $month = phabricator_format_local_time($now, $user, 'm');
+ $day = phabricator_format_local_time($now, $user, 'j');
+ $statuses = id(new PhabricatorCalendarEventQuery())
+ ->setViewer($user)
+ ->withInvitedPHIDs(array($user->getPHID()))
+ ->withDateRange(
+ strtotime("{$year}-{$month}-{$day}"),
+ strtotime("{$year}-{$month}-{$day} +7 days"))
+ ->execute();
+
+ $events = array();
+ foreach ($statuses as $status) {
+ $event = new AphrontCalendarEventView();
+ $event->setEpochRange($status->getDateFrom(), $status->getDateTo());
+
+ $status_text = $status->getHumanStatus();
+ $event->setUserPHID($status->getUserPHID());
+ $event->setName($status_text);
+ $event->setDescription($status->getDescription());
+ $event->setEventID($status->getID());
+ $key = date('Y-m-d', $event->getEpochStart());
+ $events[$key][] = $event;
+ // Populate multiday events
+ // Better means?
+ $next_day = strtotime("{$key} +1 day");
+ if ($event->getEpochEnd() >= $next_day) {
+ $nextkey = date('Y-m-d', $next_day);
+ $events[$nextkey][] = $event;
+ }
+ }
+
+ $i = 0;
+ $week = array();
+ for ($i = 0;$i <= 6;$i++) {
+ $datetime = strtotime("{$year}-{$month}-{$day} +{$i} days");
+ $headertext = phabricator_format_local_time($datetime, $user, 'l, M d');
+ $this_day = date('Y-m-d', $datetime);
+
+ $list = new PHUICalendarListView();
+ $list->setUser($user);
+ $list->showBlankState(true);
+ if (isset($events[$this_day])) {
+ foreach ($events[$this_day] as $event) {
+ $list->addEvent($event);
+ }
+ }
+
+ $header = phutil_tag(
+ 'a',
+ array(
+ 'href' => $this->getRequest()->getRequestURI().'calendar/'
+ ),
+ $headertext);
+
+ $calendar = new PHUICalendarWidgetView();
+ $calendar->setHeader($header);
+ $calendar->setCalendarList($list);
+ $week[] = $calendar;
+ }
+
+ return phutil_tag_div(
+ 'profile-calendar',
+ $week);
+ }
}
Index: src/view/phui/calendar/PHUICalendarListView.php
===================================================================
--- /dev/null
+++ src/view/phui/calendar/PHUICalendarListView.php
@@ -0,0 +1,138 @@
+<?php
+
+final class PHUICalendarListView extends AphrontTagView {
+
+ private $events = array();
+ private $blankState;
+
+ protected $user;
+
+ public function addEvent(AphrontCalendarEventView $event) {
+ $this->events[] = $event;
+ return $this;
+ }
+
+ public function setUser($user) {
+ $this->user = $user;
+ return $this;
+ }
+
+ public function showBlankState($state) {
+ $this->blankState = $state;
+ return $this;
+ }
+
+ public function getTagName() {
+ return 'div';
+ }
+
+ public function getTagAttributes() {
+ require_celerity_resource('phui-calendar-css');
+ require_celerity_resource('phui-calendar-list-css');
+ return array('class' => 'phui-calendar-day-list');
+ }
+
+ protected function getTagContent() {
+ if (!$this->blankState && empty($this->events)) {
+ return '';
+ }
+
+ $events = msort($this->events, 'getEpochStart');
+
+ // All Day Event (well, 23 hours, 59 minutes worth)
+ $timespan = ((3600 * 24) - 60);
+
+ $singletons = array();
+ $allday = false;
+ foreach ($events as $event) {
+ $color = $event->getColor();
+
+ $length = ($event->getEpochEnd() - $event->getEpochStart());
+ if ($length >= $timespan) {
+ $timelabel = pht('All Day');
+ } else {
+ $timelabel = phabricator_time($event->getEpochStart(), $this->user);
+ }
+
+ $dot = phutil_tag(
+ 'span',
+ array(
+ 'class' => 'phui-calendar-list-dot'),
+ '');
+ $title = phutil_tag(
+ 'span',
+ array(
+ 'class' => 'phui-calendar-list-title'),
+ $this->renderEventLink($event, $allday));
+ $time = phutil_tag(
+ 'span',
+ array(
+ 'class' => 'phui-calendar-list-time'),
+ $timelabel);
+
+ $singletons[] = phutil_tag(
+ 'li',
+ array(
+ 'class' => 'phui-calendar-list-item phui-calendar-'.$color
+ ),
+ array(
+ $dot,
+ $title,
+ $time));
+ }
+
+ if (empty($singletons)) {
+ $singletons[] = phutil_tag(
+ 'li',
+ array(
+ 'class' => 'phui-calendar-list-item-empty'
+ ),
+ pht('Clear sailing ahead.'));
+ }
+
+ $list = phutil_tag(
+ 'ul',
+ array(
+ 'class' => 'phui-calendar-list'
+ ),
+ $singletons);
+
+ return $list;
+ }
+
+ private function renderEventLink($event) {
+
+ Javelin::initBehavior('phabricator-tooltips');
+
+ // Multiple Days
+ $timespan = ((3600 * 24) + 60);
+ $length = ($event->getEpochEnd() - $event->getEpochStart());
+ if ($length >= $timespan) {
+ $tip = pht('%s, Until: %s', $event->getName(),
+ phabricator_date($event->getEpochEnd(), $this->user));
+ } else {
+ $tip = pht('%s, Until: %s', $event->getName(),
+ phabricator_time($event->getEpochEnd(), $this->user));
+ }
+
+ $description = $event->getDescription();
+ if (strlen($description) == 0) {
+ $description = pht('(%s)', $event->getName());
+ }
+
+ $anchor = javelin_tag(
+ 'a',
+ array(
+ 'sigil' => 'has-tooltip',
+ 'class' => 'phui-calendar-item-link',
+ 'href' => '/calendar/event/view/'.$event->getEventID().'/',
+ 'meta' => array(
+ 'tip' => $tip,
+ 'size' => 200,
+ ),
+ ),
+ $description);
+
+ return $anchor;
+ }
+}
Index: src/view/phui/calendar/PHUICalendarMonthView.php
===================================================================
--- src/view/phui/calendar/PHUICalendarMonthView.php
+++ src/view/phui/calendar/PHUICalendarMonthView.php
@@ -8,6 +8,7 @@
private $holidays = array();
private $events = array();
private $browseURI;
+ private $image;
public function setBrowseURI($browse_uri) {
$this->browseURI = $browse_uri;
@@ -22,6 +23,11 @@
return $this;
}
+ public function setImage($uri) {
+ $this->image = $uri;
+ return $this;
+ }
+
public function setHolidays(array $holidays) {
assert_instances_of($holidays, 'PhabricatorCalendarHoliday');
$this->holidays = mpull($holidays, null, 'getDay');
@@ -92,6 +98,7 @@
"\xC2\xA0")); // &nbsp;
}
+ $list_events = array();
foreach ($events as $event) {
if ($event->getEpochStart() >= $epoch_end) {
// This list is sorted, so we can stop looking.
@@ -99,13 +106,16 @@
}
if ($event->getEpochStart() < $epoch_end &&
$event->getEpochEnd() > $epoch_start) {
- $show_events[$event->getUserPHID()] = $this->renderEvent(
- $event,
- $epoch_start,
- $epoch_end);
+ $list_events[] = $event;
}
}
+ $list = new PHUICalendarListView();
+ $list->setUser($this->user);
+ foreach ($list_events as $item) {
+ $list->addEvent($item);
+ }
+
$holiday_markup = null;
if ($holiday) {
$name = $holiday->getName();
@@ -123,7 +133,7 @@
array(
phutil_tag_div('phui-calendar-date-number', $day_number),
$holiday_markup,
- phutil_implode_html("\n", $show_events),
+ $list,
));
}
@@ -227,6 +237,10 @@
$header->setButtonBar($button_bar);
}
+ if ($this->image) {
+ $header->setImage($this->image);
+ }
+
return $header;
}
@@ -293,60 +307,4 @@
return $days;
}
- private function renderEvent(
- AphrontCalendarEventView $event,
- $epoch_start,
- $epoch_end) {
-
- $user = $this->user;
-
- $event_start = $event->getEpochStart();
- $event_end = $event->getEpochEnd();
-
- $classes = array();
- $when = array();
-
- $classes[] = 'phui-calendar-event';
- if ($event_start < $epoch_start) {
- $classes[] = 'phui-calendar-event-continues-before';
- $when[] = 'Started '.phabricator_datetime($event_start, $user);
- } else {
- $when[] = 'Starts at '.phabricator_time($event_start, $user);
- }
-
- if ($event_end > $epoch_end) {
- $classes[] = 'phui-calendar-event-continues-after';
- $when[] = 'Ends '.phabricator_datetime($event_end, $user);
- } else {
- $when[] = 'Ends at '.phabricator_time($event_end, $user);
- }
-
- Javelin::initBehavior('phabricator-tooltips');
-
- $info = $event->getName();
- if ($event->getDescription()) {
- $info .= "\n\n".$event->getDescription();
- }
-
- $text_div = javelin_tag(
- 'a',
- array(
- 'sigil' => 'has-tooltip',
- 'meta' => array(
- 'tip' => $info."\n\n".implode("\n", $when),
- 'size' => 240,
- ),
- 'class' => 'phui-calendar-event-text',
- 'href' => '/calendar/event/view/'.$event->getEventID().'/',
- ),
- phutil_utf8_shorten($event->getName(), 32));
-
- return javelin_tag(
- 'div',
- array(
- 'class' => implode(' ', $classes),
- ),
- $text_div);
- }
-
}
Index: src/view/phui/calendar/PHUICalendarWidgetView.php
===================================================================
--- /dev/null
+++ src/view/phui/calendar/PHUICalendarWidgetView.php
@@ -0,0 +1,39 @@
+<?php
+
+final class PHUICalendarWidgetView extends AphrontTagView {
+
+ private $header;
+ private $list;
+
+ public function setHeader($date) {
+ $this->header = $date;
+ return $this;
+ }
+
+ public function setCalendarList(PHUICalendarListView $list) {
+ $this->list = $list;
+ return $this;
+ }
+
+ public function getTagName() {
+ return 'div';
+ }
+
+ public function getTagAttributes() {
+ require_celerity_resource('phui-calendar-list-css');
+ return array('class' => 'phui-calendar-list-container');
+ }
+
+ protected function getTagContent() {
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($this->header);
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->setFlush(true)
+ ->appendChild($this->list);
+
+ return $box;
+ }
+}
Index: webroot/rsrc/css/application/profile/profile-view.css
===================================================================
--- webroot/rsrc/css/application/profile/profile-view.css
+++ webroot/rsrc/css/application/profile/profile-view.css
@@ -4,8 +4,7 @@
.device-desktop .profile-feed,
.device-tablet .profile-feed {
- max-width: 640px;
- padding: 12px 16px;
+ padding: 0 16px 16px 0;
}
.device-phone .profile-feed {
@@ -16,3 +15,26 @@
font-size: 16px;
margin-bottom: 5px;
}
+
+.profile-activity-view {
+ padding-top: 16px;
+}
+
+.profile-activity-view .profile-calendar {
+ float: left;
+ margin: 0 16px;
+}
+
+.profile-activity-view .profile-feed {
+ margin-left: 332px;
+}
+
+.device-phone .profile-activity-view .profile-calendar {
+ float: none;
+ margin: 0;
+}
+
+.device-phone .profile-activity-view .profile-feed {
+ float: none;
+ margin: 0 8px;
+}
Index: webroot/rsrc/css/phui/calendar/phui-calendar-day.css
===================================================================
--- /dev/null
+++ webroot/rsrc/css/phui/calendar/phui-calendar-day.css
@@ -0,0 +1,3 @@
+/**
+ * @provides phui-calendar-day-css
+ */
Index: webroot/rsrc/css/phui/calendar/phui-calendar-list.css
===================================================================
--- /dev/null
+++ webroot/rsrc/css/phui/calendar/phui-calendar-list.css
@@ -0,0 +1,64 @@
+/**
+ * @provides phui-calendar-list-css
+ */
+
+.phui-calendar-list-container {
+ width: 300px;
+}
+
+.device-phone .phui-calendar-list-container {
+ width: auto;
+}
+
+.phui-calendar-list-container .phui-object-box {
+ border-bottom: none;
+ margin: 0;
+}
+
+.phui-calendar-list-container:last-child .phui-object-box {
+ border-bottom: 1px solid {$blueborder};
+}
+
+.phui-calendar-list-container .phui-object-box .phui-header-shell h1 {
+ padding: 6px 0;
+}
+
+.phui-calendar-list {
+ padding: 16px 12px;
+}
+
+.phui-calendar-list-item {
+ position: relative;
+}
+
+.phui-calendar-list-dot {
+ position: relative;
+ display: inline-block;
+ width: 5px;
+ height: 5px;
+ margin-right: 6px;
+ top: -5px;
+ border-radius: 10px;
+ border: 1px solid transparent;
+}
+
+.phui-calendar-list-title {
+ width: 200px;
+ display: inline-block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.phui-calendar-list-item .phui-calendar-list-time {
+ position: absolute;
+ width: 60px;
+ right: 0;
+ top: 0;
+ color: {$lightgreytext};
+ text-align: right;
+}
+
+.phui-calendar-list-item-empty {
+ color: {$lightgreytext};
+}
Index: webroot/rsrc/css/phui/calendar/phui-calendar-month.css
===================================================================
--- webroot/rsrc/css/phui/calendar/phui-calendar-month.css
+++ webroot/rsrc/css/phui/calendar/phui-calendar-month.css
@@ -23,6 +23,7 @@
table.phui-calendar-view td div.phui-calendar-day {
min-height: 125px;
+ position: relative;
}
.phui-calendar-holiday {
@@ -43,12 +44,14 @@
border-color: {$thinblueborder};
border-style: solid;
border-width: 0 0 1px 1px;
- float: right;
+ position: absolute;
background: #ffffff;
width: 16px;
height: 16px;
text-align: center;
- margin-bottom: 3px;
+ top: 0;
+ right: 0;
+ z-index: 10;
}
.phui-calendar-not-work-day {
@@ -63,40 +66,36 @@
background-color: {$greybackground};
}
-.phui-calendar-event {
- clear: both;
- background: {$sky};
- font-size: 11px;
- margin: 2px 0;
- border-radius: 3px;
- padding: 3px 5%;
- width: 90%;
- overflow: hidden;
+.phui-calendar-event-empty {
+ border-color: transparent;
+ background: transparent;
}
-.phui-calendar-event a:link {
- color: #fff;
+.phui-calendar-view .phui-calendar-list {
+ padding: 8px;
}
-.phui-calendar-event-empty {
- border-color: transparent;
- background: transparent;
+.phui-calendar-view .phui-calendar-list li:first-child {
+ margin-right: 16px;
}
-.phui-calendar-event-text {
- color: #fff;
- overflow: hidden;
- white-space: nowrap;
+.phui-calendar-view .phui-calendar-list-dot {
+ width: 3px;
+ height: 3px;
+ margin-right: 4px;
+ border-radius: 10px;
+ position: absolute;
+ top: 5px;
+ left: 0;
}
-.phui-calendar-event-continues-before {
- border-top-left-radius: 0px;
- border-bottom-left-radius: 0px;
- border-left-width: 0px;
+.phui-calendar-view .phui-calendar-list-title {
+ width: auto;
+ margin-left: 10px;
+ white-space: normal;
+ word-break: break-word;
}
-.phui-calendar-event-continues-after {
- border-top-right-radius: 0px;
- border-bottom-right-radius: 0px;
- border-right-width: 0px;
+.phui-calendar-view .phui-calendar-list-time {
+ display: none;
}
Index: webroot/rsrc/css/phui/calendar/phui-calendar.css
===================================================================
--- /dev/null
+++ webroot/rsrc/css/phui/calendar/phui-calendar.css
@@ -0,0 +1,107 @@
+/**
+ * @provides phui-calendar-css
+ */
+
+.phui-calendar-red a {
+ color: {$red};
+}
+
+.phui-calendar-orange a {
+ color: {$orange};
+}
+
+.phui-calendar-yellow a {
+ color: {$yellow};
+}
+
+.phui-calendar-green a {
+ color: {$green}
+}
+
+.phui-calendar-blue a {
+ color: {$blue};
+}
+
+.phui-calendar-sky a {
+ color: {$sky};
+}
+
+.phui-calendar-indigo a {
+ color: {$indigo};
+}
+
+.phui-calendar-violet a {
+ color: {$violet};
+}
+
+.phui-calendar-bg-red {
+ background-color: {$lightred};
+}
+
+.phui-calendar-bg-orange {
+ background-color: {$lightorange};
+}
+
+.phui-calendar-bg-yellow {
+ background-color: {$lightyellow};
+}
+
+.phui-calendar-bg-green {
+ background-color: {$lightgreen}
+}
+
+.phui-calendar-bg-blue {
+ background-color: {$lightblue};
+}
+
+.phui-calendar-bg-sky {
+ background-color: {$lightsky};
+}
+
+.phui-calendar-bg-indigo {
+ background-color: {$lightindigo};
+}
+
+.phui-calendar-bg-violet {
+ background-color: {$lightviolet};
+}
+
+.phui-calendar-red .phui-calendar-list-dot {
+ background-color: {$red};
+ border-color: {$red};
+}
+
+.phui-calendar-orange .phui-calendar-list-dot {
+ background-color: {$orange};
+ border-color: {$orange};
+}
+
+.phui-calendar-yellow .phui-calendar-list-dot {
+ background-color: {$orange};
+ border-color: {$orange};
+}
+
+.phui-calendar-green .phui-calendar-list-dot {
+ background-color: {$green};
+ border-color: {$green};
+}
+
+.phui-calendar-blue .phui-calendar-list-dot {
+ background-color: {$blue};
+ border-color: {$blue};
+}
+
+.phui-calendar-sky .phui-calendar-list-dot {
+ background-color: {$sky};
+ border-color: {$sky};
+}
+
+.phui-calendar-indigo .phui-calendar-list-dot {
+ background-color: {$indigo};
+ border-color: {$indigo};
+}
+
+.phui-calendar-violet .phui-calendar-list-dot {
+ background-color: {$violet};
+ border-color: {$violet};
+}
Index: webroot/rsrc/css/phui/phui-box.css
===================================================================
--- webroot/rsrc/css/phui/phui-box.css
+++ webroot/rsrc/css/phui/phui-box.css
@@ -7,10 +7,3 @@
border-bottom: 1px solid {$blueborder};
background-color: #fff;
}
-
-.device-phone .phui-box {
- border-left: none;
- border-right: none;
- margin-left: 0;
- margin-right: 0;
-}
Index: webroot/rsrc/css/phui/phui-object-box.css
===================================================================
--- webroot/rsrc/css/phui/phui-object-box.css
+++ webroot/rsrc/css/phui/phui-object-box.css
@@ -2,7 +2,7 @@
* @provides phui-object-box-css
*/
-.phui-object-box.phui-object-box-flush {
+div.phui-object-box.phui-object-box-flush {
margin-top: 0;
}
@@ -29,9 +29,5 @@
}
.device-phone .phui-object-box {
- margin-top: 0;
-}
-
-.device-phone .phui-object-box + .phui-object-box {
- border-top: none;
+ margin: 8px 8px 0 8px;
}

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 7, 12:30 PM (20 h, 16 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7098810
Default Alt Text
D8317.diff (38 KB)

Event Timeline