@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 PholioTransactionView
4 extends PhabricatorApplicationTransactionView {
5
6 private $mock;
7
8 public function setMock($mock) {
9 $this->mock = $mock;
10 return $this;
11 }
12
13 public function getMock() {
14 return $this->mock;
15 }
16
17 protected function shouldGroupTransactions(
18 PhabricatorApplicationTransaction $u,
19 PhabricatorApplicationTransaction $v) {
20
21 if ($u->getAuthorPHID() != $v->getAuthorPHID()) {
22 // Don't group transactions by different authors.
23 return false;
24 }
25
26 if (($v->getDateCreated() - $u->getDateCreated()) > 60) {
27 // Don't group if transactions happened more than 60s apart.
28 return false;
29 }
30
31 switch ($u->getTransactionType()) {
32 case PhabricatorTransactions::TYPE_COMMENT:
33 case PholioMockInlineTransaction::TRANSACTIONTYPE:
34 break;
35 default:
36 return false;
37 }
38
39 switch ($v->getTransactionType()) {
40 case PholioMockInlineTransaction::TRANSACTIONTYPE:
41 return true;
42 }
43
44 return parent::shouldGroupTransactions($u, $v);
45 }
46
47 protected function renderTransactionContent(
48 PhabricatorApplicationTransaction $xaction) {
49
50 $out = array();
51
52 $group = $xaction->getTransactionGroup();
53 $type = $xaction->getTransactionType();
54 if ($type == PholioMockInlineTransaction::TRANSACTIONTYPE) {
55 array_unshift($group, $xaction);
56 } else {
57 $out[] = parent::renderTransactionContent($xaction);
58 }
59
60 if (!$group) {
61 return $out;
62 }
63
64 $inlines = array();
65 foreach ($group as $xaction) {
66 switch ($xaction->getTransactionType()) {
67 case PholioMockInlineTransaction::TRANSACTIONTYPE:
68 $inlines[] = $xaction;
69 break;
70 default:
71 throw new Exception(pht('Unknown grouped transaction type!'));
72 }
73 }
74
75 if ($inlines) {
76 $icon = id(new PHUIIconView())
77 ->setIcon('fa-comment bluegrey msr');
78 $header = phutil_tag(
79 'div',
80 array(
81 'class' => 'phabricator-transaction-subheader',
82 ),
83 array($icon, pht('Inline Comments')));
84
85 $out[] = $header;
86 foreach ($inlines as $inline) {
87 if (!$inline->getComment()) {
88 continue;
89 }
90 $out[] = $this->renderInlineContent($inline);
91 }
92 }
93
94 return $out;
95 }
96
97 private function renderInlineContent(PholioTransaction $inline) {
98 $comment = $inline->getComment();
99 $mock = $this->getMock();
100 $images = $mock->getImages();
101 $images = mpull($images, null, 'getID');
102
103 $image = idx($images, $comment->getImageID());
104 if (!$image) {
105 throw new Exception(pht('No image attached!'));
106 }
107
108 $file = $image->getFile();
109 if (!$file->isViewableImage()) {
110 throw new Exception(pht('File is not viewable.'));
111 }
112
113 $image_uri = $file->getBestURI();
114
115 $thumb = id(new PHUIImageMaskView())
116 ->addClass('mrl')
117 ->setImage($image_uri)
118 ->setDisplayHeight(100)
119 ->setDisplayWidth(200)
120 ->withMask(true)
121 ->centerViewOnPoint(
122 $comment->getX(), $comment->getY(),
123 $comment->getHeight(), $comment->getWidth());
124
125 $link = phutil_tag(
126 'a',
127 array(
128 'href' => '#',
129 'class' => 'pholio-transaction-inline-image-anchor',
130 ),
131 $thumb);
132
133 $inline_comment = parent::renderTransactionContent($inline);
134
135 return phutil_tag(
136 'div',
137 array('class' => 'pholio-transaction-inline-comment'),
138 array($link, $inline_comment));
139 }
140
141}