Roughly style the new "flank" paths UI
[phabricator/blender.git] / src / applications / differential / view / DifferentialChangesetFileTreeSideNavBuilder.php
blobe8852a5c526eb965ebc60bc4821065888766fbcc
1 <?php
3 final class DifferentialChangesetFileTreeSideNavBuilder extends Phobject {
5 private $title;
6 private $baseURI;
7 private $anchorName;
8 private $collapsed = false;
9 private $width;
11 public function setAnchorName($anchor_name) {
12 $this->anchorName = $anchor_name;
13 return $this;
15 public function getAnchorName() {
16 return $this->anchorName;
19 public function setBaseURI(PhutilURI $base_uri) {
20 $this->baseURI = $base_uri;
21 return $this;
23 public function getBaseURI() {
24 return $this->baseURI;
27 public function setTitle($title) {
28 $this->title = $title;
29 return $this;
31 public function getTitle() {
32 return $this->title;
35 public function setCollapsed($collapsed) {
36 $this->collapsed = $collapsed;
37 return $this;
40 public function setWidth($width) {
41 $this->width = $width;
42 return $this;
45 public function build(array $changesets) {
46 assert_instances_of($changesets, 'DifferentialChangeset');
48 $nav = id(new AphrontSideNavFilterView())
49 ->setBaseURI($this->getBaseURI())
50 ->setFlexible(true)
51 ->setCollapsed($this->collapsed)
52 ->setWidth($this->width);
54 $anchor = $this->getAnchorName();
56 $tree = new PhutilFileTree();
57 foreach ($changesets as $changeset) {
58 try {
59 $tree->addPath($changeset->getFilename(), $changeset);
60 } catch (Exception $ex) {
61 // TODO: See T1702. When viewing the versus diff of diffs, we may
62 // have files with the same filename. For example, if you have a setup
63 // like this in SVN:
65 // a/
66 // README
67 // b/
68 // README
70 // ...and you run "arc diff" once from a/, and again from b/, you'll
71 // get two diffs with path README. However, in the versus diff view we
72 // will compute their absolute repository paths and detect that they
73 // aren't really the same file. This is correct, but causes us to
74 // throw when inserting them.
76 // We should probably compute the smallest unique path for each file
77 // and show these as "a/README" and "b/README" when diffed against
78 // one another. However, we get this wrong in a lot of places (the
79 // other TOC shows two "README" files, and we generate the same anchor
80 // hash for both) so I'm just stopping the bleeding until we can get
81 // a proper fix in place.
85 require_celerity_resource('phabricator-filetree-view-css');
87 $filetree = array();
89 $path = $tree;
90 while (($path = $path->getNextNode())) {
91 $data = $path->getData();
93 $classes = array();
94 $classes[] = 'phabricator-filetree-item';
96 $name = $path->getName();
97 $style = 'padding-left: '.(2 + (3 * $path->getDepth())).'px';
99 $href = null;
100 if ($data) {
101 $href = '#'.$data->getAnchorName();
102 $title = $name;
104 $icon = $data->newFileTreeIcon();
105 $classes[] = $data->getFileTreeClass();
107 $count = phutil_tag(
108 'span',
109 array(
110 'class' => 'filetree-progress-hint',
111 'id' => 'tree-node-'.$data->getAnchorName(),
113 } else {
114 $name .= '/';
115 $title = $path->getFullPath().'/';
116 $icon = id(new PHUIIconView())
117 ->setIcon('fa-folder-open blue');
119 $count = null;
122 $name_element = phutil_tag(
123 'span',
124 array(
125 'class' => 'phabricator-filetree-name',
127 $name);
130 $filetree[] = javelin_tag(
131 $href ? 'a' : 'span',
132 array(
133 'href' => $href,
134 'style' => $style,
135 'title' => $title,
136 'class' => implode(' ', $classes),
138 array($count, $icon, $name_element));
140 $tree->destroy();
142 $filetree = phutil_tag(
143 'div',
144 array(
145 'class' => 'phabricator-filetree',
147 $filetree);
149 Javelin::initBehavior('phabricator-file-tree', array());
151 $nav->addLabel(pht('Changed Files'));
152 $nav->addCustomBlock($filetree);
153 $nav->setActive(true);
154 $nav->selectFilter(null);
155 return $nav;