@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<?php
2
3final class PHUIFeedStoryView extends AphrontView {
4
5 private $title;
6 private $image;
7 private $imageHref;
8 private $appIcon;
9 private $phid;
10 private $epoch;
11 private $viewed;
12 private $href;
13 private $pontification = null;
14 private $tokenBar = array();
15 private $projects = array();
16 private $actions = array();
17 private $chronologicalKey;
18 private $tags;
19 private $authorIcon;
20 private $showTimestamp = true;
21
22 public function setTags($tags) {
23 $this->tags = $tags;
24 return $this;
25 }
26
27 public function getTags() {
28 return $this->tags;
29 }
30
31 public function setChronologicalKey($chronological_key) {
32 $this->chronologicalKey = $chronological_key;
33 return $this;
34 }
35
36 public function getChronologicalKey() {
37 return $this->chronologicalKey;
38 }
39
40 public function setTitle($title) {
41 $this->title = $title;
42 return $this;
43 }
44
45 public function getTitle() {
46 return $this->title;
47 }
48
49 public function setEpoch($epoch) {
50 $this->epoch = $epoch;
51 return $this;
52 }
53
54 public function setImage($image) {
55 $this->image = $image;
56 return $this;
57 }
58
59 public function getImage() {
60 return $this->image;
61 }
62
63 public function setImageHref($image_href) {
64 $this->imageHref = $image_href;
65 return $this;
66 }
67
68 public function setAppIcon($icon) {
69 $this->appIcon = $icon;
70 return $this;
71 }
72
73 public function setViewed($viewed) {
74 $this->viewed = $viewed;
75 return $this;
76 }
77
78 public function getViewed() {
79 return $this->viewed;
80 }
81
82 public function setHref($href) {
83 $this->href = $href;
84 return $this;
85 }
86
87 public function setAuthorIcon($author_icon) {
88 $this->authorIcon = $author_icon;
89 return $this;
90 }
91
92 public function getAuthorIcon() {
93 return $this->authorIcon;
94 }
95
96 public function setTokenBar(array $tokens) {
97 $this->tokenBar = $tokens;
98 return $this;
99 }
100
101 public function setShowTimestamp($show_timestamp) {
102 $this->showTimestamp = $show_timestamp;
103 return $this;
104 }
105
106 public function getShowTimestamp() {
107 return $this->showTimestamp;
108 }
109
110 public function addProject($project) {
111 $this->projects[] = $project;
112 return $this;
113 }
114
115 public function addAction(PHUIIconView $action) {
116 $this->actions[] = $action;
117 return $this;
118 }
119
120 public function setPontification($text, $title = null) {
121 if ($title) {
122 $title = phutil_tag('h2', array(), $title);
123 }
124 $copy = phutil_tag(
125 'div',
126 array(
127 'class' => 'phui-feed-story-bigtext-post',
128 ),
129 array(
130 $title,
131 $text,
132 ));
133 $this->appendChild($copy);
134 return $this;
135 }
136
137 public function getHref() {
138 return $this->href;
139 }
140
141 public function renderNotification($user) {
142 $classes = array(
143 'phabricator-notification',
144 );
145
146 if (!$this->viewed) {
147 $classes[] = 'phabricator-notification-unread';
148 }
149
150 if ($this->getShowTimestamp()) {
151 if ($this->epoch) {
152 if ($user) {
153 $marker = id(new PHUIIconView())
154 ->setIcon('fa-circle')
155 ->addClass('phabricator-notification-status');
156 $date = phabricator_datetime($this->epoch, $user);
157 $foot = phutil_tag(
158 'span',
159 array(
160 'class' => 'phabricator-notification-date',
161 ),
162 $date);
163 $foot = phutil_tag(
164 'div',
165 array(
166 'class' => 'phabricator-notification-foot',
167 ),
168 array(
169 $marker,
170 $date,
171 ));
172 } else {
173 $foot = null;
174 }
175 } else {
176 $foot = pht('No time specified.');
177 }
178 } else {
179 $foot = null;
180 }
181
182 return javelin_tag(
183 'div',
184 array(
185 'class' => implode(' ', $classes),
186 'sigil' => 'notification',
187 'meta' => array(
188 'href' => $this->getHref(),
189 ),
190 ),
191 array($this->title, $foot));
192 }
193
194 public function render() {
195
196 require_celerity_resource('phui-feed-story-css');
197 Javelin::initBehavior('phui-hovercards');
198
199 $body = null;
200 $foot = null;
201
202 $actor = new PHUIIconView();
203 $actor->addClass('phui-feed-story-actor');
204
205 $author_icon = $this->getAuthorIcon();
206
207 if ($this->image) {
208 $actor->addClass('phui-feed-story-actor-image');
209 $actor->setImage($this->image);
210 } else if ($author_icon) {
211 $actor->addClass('phui-feed-story-actor-icon');
212 $actor->setIcon($author_icon);
213 }
214
215 if ($this->imageHref) {
216 $actor->setHref($this->imageHref);
217 }
218
219 if ($this->epoch) {
220 // TODO: This is really bad; when rendering through Conduit and via
221 // renderText() we don't have a user.
222 if ($this->hasViewer()) {
223 $foot = phabricator_datetime($this->epoch, $this->getViewer());
224 } else {
225 $foot = null;
226 }
227 } else {
228 $foot = pht('No time specified.');
229 }
230
231 if ($this->chronologicalKey) {
232 $foot = phutil_tag(
233 'a',
234 array(
235 'href' => '/feed/'.$this->chronologicalKey.'/',
236 ),
237 $foot);
238 }
239
240 $icon = null;
241 if ($this->appIcon) {
242 $icon = id(new PHUIIconView())
243 ->setIcon($this->appIcon);
244 }
245
246 $action_list = array();
247 $icons = null;
248 foreach ($this->actions as $action) {
249 $action_list[] = phutil_tag(
250 'li',
251 array(
252 'class' => 'phui-feed-story-action-item',
253 ),
254 $action);
255 }
256 if (!empty($action_list)) {
257 $icons = phutil_tag(
258 'ul',
259 array(
260 'class' => 'phui-feed-story-action-list',
261 ),
262 $action_list);
263 }
264
265 $head = phutil_tag(
266 'div',
267 array(
268 'class' => 'phui-feed-story-head',
269 ),
270 array(
271 $actor,
272 nonempty($this->title, pht('Untitled Story')),
273 $icons,
274 ));
275
276 if (!empty($this->tokenBar)) {
277 $tokenview = phutil_tag(
278 'div',
279 array(
280 'class' => 'phui-feed-token-bar',
281 ),
282 $this->tokenBar);
283 $this->appendChild($tokenview);
284 }
285
286 $body_content = $this->renderChildren();
287 if ($body_content) {
288 $body = phutil_tag(
289 'div',
290 array(
291 'class' => 'phui-feed-story-body phabricator-remarkup',
292 ),
293 $body_content);
294 }
295
296 $tags = null;
297 if ($this->tags) {
298 $tags = array(
299 " \xC2\xB7 ",
300 $this->tags,
301 );
302 }
303
304 $foot = phutil_tag(
305 'div',
306 array(
307 'class' => 'phui-feed-story-foot',
308 ),
309 array(
310 $icon,
311 $foot,
312 $tags,
313 ));
314
315 $classes = array('phui-feed-story');
316
317 return id(new PHUIBoxView())
318 ->addClass(implode(' ', $classes))
319 ->setBorder(true)
320 ->addMargin(PHUI::MARGIN_MEDIUM_BOTTOM)
321 ->appendChild(array($head, $body, $foot));
322 }
323
324}