@@ -194,7 +194,7 @@ public function processRequest() {
194
194
array (
195
195
'href ' => $ request_uri
196
196
->alter ('large ' , 'true ' )
197
- ->setFragment ('differential-review- toc ' ),
197
+ ->setFragment ('toc ' ),
198
198
),
199
199
'Show All Files Inline ' ).
200
200
"</strong> " );
@@ -395,12 +395,22 @@ public function processRequest() {
395
395
PhabricatorFeedStoryNotification::updateObjectNotificationViews (
396
396
$ user , $ revision ->getPHID ());
397
397
398
- return $ this ->buildStandardPageResponse (
398
+ $ top_anchor = id (new PhabricatorAnchorView ())
399
+ ->setAnchorName ('top ' )
400
+ ->setNavigationMarker (true );
401
+
402
+ $ nav = $ this ->buildSideNavView ($ revision , $ changesets );
403
+ $ nav ->selectFilter ('' );
404
+ $ nav ->appendChild (
399
405
array (
400
406
$ reviewer_warning ,
407
+ $ top_anchor ,
401
408
$ revision_detail ,
402
409
$ page_pane ,
403
- ),
410
+ ));
411
+
412
+ return $ this ->buildApplicationPage (
413
+ $ nav ,
404
414
array (
405
415
'title ' => 'D ' .$ revision ->getID ().' ' .$ revision ->getTitle (),
406
416
));
@@ -996,4 +1006,79 @@ private function buildRawDiffResponse(
996
1006
return id (new AphrontRedirectResponse ())->setURI ($ file ->getBestURI ());
997
1007
998
1008
}
1009
+
1010
+ private function buildSideNavView (
1011
+ DifferentialRevision $ revision ,
1012
+ array $ changesets ) {
1013
+
1014
+ $ nav = new AphrontSideNavFilterView ();
1015
+ $ nav ->setBaseURI (new PhutilURI ('/D ' .$ revision ->getID ()));
1016
+ $ nav ->setFlexible (true );
1017
+
1018
+ $ nav ->addFilter ('top ' , 'D ' .$ revision ->getID (), '#top ' ,
1019
+ $ relative = false ,
1020
+ 'phabricator-active-nav-focus ' );
1021
+
1022
+ $ tree = new PhutilFileTree ();
1023
+ foreach ($ changesets as $ changeset ) {
1024
+ $ tree ->addPath ($ changeset ->getFilename (), $ changeset );
1025
+ }
1026
+
1027
+ require_celerity_resource ('phabricator-filetree-view-css ' );
1028
+
1029
+ $ filetree = array ();
1030
+
1031
+ $ path = $ tree ;
1032
+ while (($ path = $ path ->getNextNode ())) {
1033
+ $ data = $ path ->getData ();
1034
+
1035
+ $ name = $ path ->getName ();
1036
+ $ style = 'padding-left: ' .(2 + (3 * $ path ->getDepth ())).'px ' ;
1037
+
1038
+ $ href = null ;
1039
+ if ($ data ) {
1040
+ $ href = '# ' .$ data ->getAnchorName ();
1041
+ $ icon = 'phabricator-filetree-icon-file ' ;
1042
+ } else {
1043
+ $ name .= '/ ' ;
1044
+ $ icon = 'phabricator-filetree-icon-dir ' ;
1045
+ }
1046
+
1047
+ $ icon = phutil_render_tag (
1048
+ 'span ' ,
1049
+ array (
1050
+ 'class ' => 'phabricator-filetree-icon ' .$ icon ,
1051
+ ),
1052
+ '' );
1053
+
1054
+ $ name_element = phutil_render_tag (
1055
+ 'span ' ,
1056
+ array (
1057
+ 'class ' => 'phabricator-filetree-name ' ,
1058
+ ),
1059
+ phutil_escape_html ($ name ));
1060
+
1061
+ $ filetree [] = javelin_render_tag (
1062
+ $ href ? 'a ' : 'span ' ,
1063
+ array (
1064
+ 'href ' => $ href ,
1065
+ 'style ' => $ style ,
1066
+ 'title ' => $ name ,
1067
+ 'class ' => 'phabricator-filetree-item ' ,
1068
+ ),
1069
+ $ icon .$ name_element );
1070
+ }
1071
+ $ tree ->destroy ();
1072
+
1073
+ $ filetree =
1074
+ '<div class="phabricator-filetree"> ' .
1075
+ implode ("\n" , $ filetree ).
1076
+ '</div> ' ;
1077
+ $ nav ->addFilter ('toc ' , 'Table of Contents ' , '#toc ' );
1078
+ $ nav ->addCustomBlock ($ filetree );
1079
+ $ nav ->addFilter ('comment ' , 'Add Comment ' , '#comment ' );
1080
+ $ nav ->setActive (true );
1081
+
1082
+ return $ nav ;
1083
+ }
999
1084
}
0 commit comments