diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
index 76c6cbaf27..71d4547559 100644
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -1352,7 +1352,7 @@ celerity_register_resource_map(array(
),
'phabricator-feed-css' =>
array(
- 'uri' => '/res/32e5879b/rsrc/css/application/feed/feed.css',
+ 'uri' => '/res/7d1d0015/rsrc/css/application/feed/feed.css',
'type' => 'css',
'requires' =>
array(
@@ -1409,7 +1409,7 @@ celerity_register_resource_map(array(
),
'phabricator-profile-css' =>
array(
- 'uri' => '/res/ebe1ac2f/rsrc/css/application/profile/profile-view.css',
+ 'uri' => '/res/9869d10b/rsrc/css/application/profile/profile-view.css',
'type' => 'css',
'requires' =>
array(
diff --git a/src/applications/feed/builder/feed/PhabricatorFeedBuilder.php b/src/applications/feed/builder/feed/PhabricatorFeedBuilder.php
index 3de6204571..147414f520 100644
--- a/src/applications/feed/builder/feed/PhabricatorFeedBuilder.php
+++ b/src/applications/feed/builder/feed/PhabricatorFeedBuilder.php
@@ -50,18 +50,44 @@ final class PhabricatorFeedBuilder {
$null_view = new AphrontNullView();
- $views = array();
+ require_celerity_resource('phabricator-feed-css');
+
+ $last_date = null;
+ $today = phabricator_date(time(), $user);
foreach ($stories as $story) {
$story->setHandles($handles);
$story->setObjects($objects);
+ $date = phabricator_date($story->getEpoch(), $user);
+ if ($date == $today) {
+ $date = 'Today';
+ }
+
+ if ($date !== $last_date) {
+ if ($last_date !== null) {
+ $null_view->appendChild(
+ '
');
+ }
+ $last_date = $date;
+ $null_view->appendChild(
+ phutil_render_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-feed-story-date',
+ ),
+ phutil_escape_html($date)));
+ }
+
$view = $story->renderView();
$view->setViewer($user);
$null_view->appendChild($view);
}
- return $null_view;
+ return id(new AphrontNullView())->appendChild(
+ ''.
+ $null_view->render().
+ '
');
}
}
diff --git a/src/applications/feed/builder/feed/__init__.php b/src/applications/feed/builder/feed/__init__.php
index 914e738afd..79b122f398 100644
--- a/src/applications/feed/builder/feed/__init__.php
+++ b/src/applications/feed/builder/feed/__init__.php
@@ -7,8 +7,11 @@
phutil_require_module('phabricator', 'applications/phid/handle/data');
+phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'view/null');
+phutil_require_module('phabricator', 'view/utils');
+phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
diff --git a/src/applications/feed/story/base/PhabricatorFeedStory.php b/src/applications/feed/story/base/PhabricatorFeedStory.php
index 313ddc1bad..a6828d16c5 100644
--- a/src/applications/feed/story/base/PhabricatorFeedStory.php
+++ b/src/applications/feed/story/base/PhabricatorFeedStory.php
@@ -59,4 +59,8 @@ abstract class PhabricatorFeedStory {
return $this->data;
}
+ final public function getEpoch() {
+ return $this->getStoryData()->getEpoch();
+ }
+
}
diff --git a/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php b/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php
index 83395108ad..b4ab02028f 100644
--- a/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php
+++ b/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php
@@ -50,7 +50,7 @@ class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory {
$view->setTitle(
''.$handles[$author_phid]->renderLink().''.
- ' '.$verb.' '.
+ ' '.$verb.' revision '.
''.$handles[$revision_phid]->renderLink().'.');
$view->setEpoch($data->getEpoch());
diff --git a/src/applications/feed/story/maniphest/PhabricatorFeedStoryManiphest.php b/src/applications/feed/story/maniphest/PhabricatorFeedStoryManiphest.php
index ef27673a63..a5a45a52e4 100644
--- a/src/applications/feed/story/maniphest/PhabricatorFeedStoryManiphest.php
+++ b/src/applications/feed/story/maniphest/PhabricatorFeedStoryManiphest.php
@@ -49,7 +49,7 @@ class PhabricatorFeedStoryManiphest extends PhabricatorFeedStory {
$verb = ManiphestAction::getActionPastTenseVerb($action);
$title =
''.$handles[$author_phid]->renderLink().''.
- " {$verb} ".
+ " {$verb} task ".
''.$handles[$task_phid]->renderLink().'';
switch ($action) {
case ManiphestAction::ACTION_ASSIGN:
diff --git a/src/applications/project/controller/profile/PhabricatorProjectProfileController.php b/src/applications/project/controller/profile/PhabricatorProjectProfileController.php
index fc86ffb693..52ecb766eb 100644
--- a/src/applications/project/controller/profile/PhabricatorProjectProfileController.php
+++ b/src/applications/project/controller/profile/PhabricatorProjectProfileController.php
@@ -82,14 +82,7 @@ class PhabricatorProjectProfileController
));
$stories = $query->execute();
- $builder = new PhabricatorFeedBuilder($stories);
- $builder->setUser($user);
- $view = $builder->buildView();
-
- $content .=
- ''.
- $view->render().
- '
';
+ $content .= $this->renderStories($stories);
break;
case 'about':
$content = $this->renderAboutPage($project, $profile);
@@ -104,7 +97,7 @@ class PhabricatorProjectProfileController
throw new Exception("Unimplemented filter '{$this->page}'.");
}
- $content = ''.$content.'
';
+ $content = ''.$content.'
';
$nav_view->appendChild($content);
$header = new PhabricatorProfileHeaderView();
@@ -238,11 +231,22 @@ class PhabricatorProjectProfileController
));
$stories = $query->execute();
+ return $this->renderStories($stories);
+ }
+
+ private function renderStories(array $stories) {
+
$builder = new PhabricatorFeedBuilder($stories);
$builder->setUser($this->getRequest()->getUser());
$view = $builder->buildView();
- return $view->render();
+ return
+ ''.
+ ''.
+ '
'.
+ $view->render().
+ '
'.
+ '
';
}
diff --git a/webroot/rsrc/css/application/feed/feed.css b/webroot/rsrc/css/application/feed/feed.css
index 089357f802..e9fae34971 100644
--- a/webroot/rsrc/css/application/feed/feed.css
+++ b/webroot/rsrc/css/application/feed/feed.css
@@ -2,6 +2,11 @@
* @provides phabricator-feed-css
*/
+.phabricator-feed-frame {
+ width: 640px;
+ padding: 1em;
+}
+
.phabricator-feed-story {
padding-left: 64px;
margin: .5em 0 1em;
@@ -27,3 +32,14 @@
color: #888888;
font-size: 11px;
}
+
+.phabricator-feed-story-date {
+ color: #666666;
+ font-size: 11px;
+ border-bottom: 1px solid #eeeeee;
+ padding: .5em 0;
+}
+
+.phabricator-feed-story-date-separator {
+ margin-top: 2em;
+}
diff --git a/webroot/rsrc/css/application/profile/profile-view.css b/webroot/rsrc/css/application/profile/profile-view.css
index 43c48395f2..9d348294cf 100644
--- a/webroot/rsrc/css/application/profile/profile-view.css
+++ b/webroot/rsrc/css/application/profile/profile-view.css
@@ -70,17 +70,16 @@ td.phabricator-profile-content {
.phabricator-profile-info-group {
margin-bottom: 2em;
- background: #efefef;
- border-top: 1px solid #cccccc;
}
.phabricator-profile-info-header {
padding: 8px;
- background: #dfdfdf;
+ background: #f0f0f0;
+ border-top: 1px solid #d9d9d9;
}
.phabricator-profile-info-pane {
- padding: 8px 2em;
+ padding: 8px .5em;
}
.phabricator-profile-info-table {