@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Differential Updates View

Summary:
This adds a new view to differential called Updates.

The high-level goal of Updates is to enabled differential to be
effectively used without email notifications. I've tried doing things
like automatically deleting differential emails where I'm in the 'to'
line since they show up on the main diffential page but then there's
always the chance an important diff flies by without me seeing it. Also,
sometimes someone comments on a diff post-commit but differential
doesn't surface those diffs.

I re-created a test db on my devserver using mysqldump to get data on
revs > 230000 so I would have some test data. We need to add a simple
viewtime table but I didn't want to do that in production. Here's the
table:

CREATE TABLE differential_viewtime (
viewerPHID varchar(64) not null,
objectPHID varchar(64) not null,
viewTime int unsigned not null,
PRIMARY KEY (viewerPHID, objectPHID)
);

Issues:
-Once we turn this on, all diffs will be 'unviewed'. What do you think
about a 'Clear All' button or something?
-Maybe we should add a pager

This feature would be insanely useful, let me know what you think.

Test Plan:
Loaded Updates in my sandbox

http://phabricator.dev1577.snc6.facebook.com/differential/filter/updates/

Clicked a diff, then went back, made sure diff disappeared from Updates
list

Reviewed By: tuomaspelkonen
Reviewers: epriestley, jungejason, tuomaspelkonen
Commenters: epriestley
CC: epriestley, elynde, tuomaspelkonen
Differential Revision: 169

elynde bd0a4c0d afedb711

+116
+6
resources/sql/patches/032.viewtime.sql
··· 1 + CREATE TABLE phabricator_differential.differential_viewtime ( 2 + viewerPHID varchar(64) not null, 3 + objectPHID varchar(64) not null, 4 + viewTime int unsigned not null, 5 + PRIMARY KEY (viewerPHID, objectPHID) 6 + );
+2
src/__phutil_library_map__.php
··· 158 158 'DifferentialSubscribeController' => 'applications/differential/controller/subscribe', 159 159 'DifferentialTasksAttacher' => 'applications/differential/tasks', 160 160 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 161 + 'DifferentialViewTime' => 'applications/differential/storage/viewtime', 161 162 'DiffusionBranchInformation' => 'applications/diffusion/data/branch', 162 163 'DiffusionBranchQuery' => 'applications/diffusion/query/branch/base', 163 164 'DiffusionBranchTableView' => 'applications/diffusion/view/branchtable', ··· 585 586 'DifferentialRevisionUpdateHistoryView' => 'AphrontView', 586 587 'DifferentialRevisionViewController' => 'DifferentialController', 587 588 'DifferentialSubscribeController' => 'DifferentialController', 589 + 'DifferentialViewTime' => 'DifferentialDAO', 588 590 'DiffusionBranchTableView' => 'DiffusionView', 589 591 'DiffusionBrowseController' => 'DiffusionController', 590 592 'DiffusionBrowseFileController' => 'DiffusionController',
+10
src/applications/differential/controller/revisionlist/DifferentialRevisionListController.php
··· 90 90 ), 91 91 ), 92 92 ), 93 + 'updates' => array( 94 + 'name' => 'Updates', 95 + 'queries' => array( 96 + array( 97 + 'query' => DifferentialRevisionListData::QUERY_UPDATED_SINCE, 98 + 'header' => 99 + 'Diffs that have been updated since you\'ve last viewed them', 100 + ), 101 + ), 102 + ), 93 103 '<hr />', 94 104 'All Revisions', 95 105 'allopen' => array(
+10
src/applications/differential/controller/revisionview/DifferentialRevisionViewController.php
··· 205 205 $comment_form->setUser($user); 206 206 $comment_form->setDraft($draft); 207 207 208 + $this->updateViewTime($user->getPHID(), $revision->getPHID()); 209 + 208 210 return $this->buildStandardPageResponse( 209 211 '<div class="differential-primary-pane">'. 210 212 $revision_detail->render(). ··· 593 595 return array($changesets, $vs_map); 594 596 } 595 597 598 + private function updateViewTime($user_phid, $revision_phid) { 599 + $view_time = 600 + id(new DifferentialViewTime()) 601 + ->setViewerPHID($user_phid) 602 + ->setObjectPHID($revision_phid) 603 + ->setViewTime(time()) 604 + ->replace(); 605 + } 596 606 } 597 607 /* 598 608
+1
src/applications/differential/controller/revisionview/__init__.php
··· 15 15 phutil_require_module('phabricator', 'applications/differential/storage/diffproperty'); 16 16 phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment'); 17 17 phutil_require_module('phabricator', 'applications/differential/storage/revision'); 18 + phutil_require_module('phabricator', 'applications/differential/storage/viewtime'); 18 19 phutil_require_module('phabricator', 'applications/differential/view/addcomment'); 19 20 phutil_require_module('phabricator', 'applications/differential/view/changesetlistview'); 20 21 phutil_require_module('phabricator', 'applications/differential/view/difftableofcontents');
+29
src/applications/differential/data/revisionlist/DifferentialRevisionListData.php
··· 29 29 const QUERY_PHIDS = 'phids'; 30 30 const QUERY_CC = 'cc'; 31 31 const QUERY_ALL_OPEN = 'all-open'; 32 + const QUERY_UPDATED_SINCE = 'updated-since'; 32 33 33 34 private $ids; 34 35 private $filter; ··· 170 171 'revision.phid in (%Ls)', 171 172 $this->ids); 172 173 break; 174 + case self::QUERY_UPDATED_SINCE: 175 + $this->revisions = $this->loadAllUpdated(); 176 + break; 173 177 } 174 178 175 179 return $this->revisions; ··· 182 186 DifferentialRevisionStatus::ACCEPTED, 183 187 ); 184 188 } 189 + 190 + private function loadAllUpdated() { 191 + $revision = new DifferentialRevision(); 192 + $min_view_time = (int)PhabricatorEnv::getEnvConfig('updates.min-view-time'); 193 + 194 + $data = queryfx_all( 195 + $revision->establishConnection('r'), 196 + 'SELECT DISTINCT revision.* FROM %T revision 197 + JOIN %T rel ON rel.revisionID = revision.id 198 + AND (rel.objectPHID in (%Ls) OR revision.authorPHID in (%Ls)) 199 + LEFT JOIN %T viewtime ON viewtime.viewerPHID in (%Ls) 200 + AND viewtime.objectPHID = revision.phid 201 + WHERE GREATEST(%d, IFNULL(viewtime.viewTime, 0)) < revision.dateModified 202 + %Q', 203 + $revision->getTableName(), 204 + DifferentialRevision::RELATIONSHIP_TABLE, 205 + $this->ids, 206 + $this->ids, 207 + DifferentialRevision::TABLE_VIEW_TIME, 208 + $this->ids, 209 + $min_view_time, 210 + $this->getOrderClause()); 211 + return $revision->loadAllFromArray($data); 212 + } 213 + 185 214 186 215 private function loadAllOpen() { 187 216 return $this->loadAllWhere('status in (%Ld)', $this->getOpenStatuses());
+1
src/applications/differential/data/revisionlist/__init__.php
··· 8 8 9 9 phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus'); 10 10 phutil_require_module('phabricator', 'applications/differential/storage/revision'); 11 + phutil_require_module('phabricator', 'infrastructure/env'); 11 12 phutil_require_module('phabricator', 'storage/queryfx'); 12 13 13 14 phutil_require_module('phutil', 'utils');
+1
src/applications/differential/storage/revision/DifferentialRevision.php
··· 39 39 private $commits; 40 40 41 41 const RELATIONSHIP_TABLE = 'differential_relationship'; 42 + const TABLE_VIEW_TIME = 'differential_viewtime'; 42 43 const TABLE_COMMIT = 'differential_commit'; 43 44 44 45 const RELATION_REVIEWER = 'revw';
+43
src/applications/differential/storage/viewtime/DifferentialViewTime.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + class DifferentialViewTime extends DifferentialDAO { 20 + 21 + protected 22 + $viewerPHID, 23 + $objectPHID, 24 + $viewTime; 25 + 26 + protected function getConfiguration() { 27 + return array( 28 + self::CONFIG_OPTIMISTIC_LOCKS => false, 29 + self::CONFIG_IDS => self::IDS_MANUAL, 30 + self::CONFIG_TIMESTAMPS => false, 31 + ); 32 + } 33 + 34 + // Primary key is (viewerPHID, objectPHID) 35 + public function getIDKey() { 36 + return null; 37 + } 38 + 39 + protected function shouldInsertWhenSaved() { 40 + return true; 41 + } 42 + } 43 +
+13
src/applications/differential/storage/viewtime/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'applications/differential/storage/base'); 10 + 11 + 12 + phutil_require_source('DifferentialViewTime.php'); 13 +