mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 10:12:41 +01:00
Make "hidden" changesets sticky, and show hidden state in the filetree
Summary: Ref T13455. Make "hidden" a changeset property similar to other changeset properties. We don't need to render this on the server, so we make a request (to update the setting) and just discard the response. Test Plan: {F7375468} Maniphest Tasks: T13455 Differential Revision: https://secure.phabricator.com/D21158
This commit is contained in:
parent
a72a66caa8
commit
60de1506fe
10 changed files with 229 additions and 37 deletions
|
@ -12,7 +12,7 @@ return array(
|
|||
'core.pkg.css' => 'dd5f04a3',
|
||||
'core.pkg.js' => '544bc792',
|
||||
'differential.pkg.css' => 'cb99cd21',
|
||||
'differential.pkg.js' => '6c315e3f',
|
||||
'differential.pkg.js' => '54613dd5',
|
||||
'diffusion.pkg.css' => '42c75c37',
|
||||
'diffusion.pkg.js' => 'a98c0bf7',
|
||||
'maniphest.pkg.css' => '35995d6d',
|
||||
|
@ -59,7 +59,7 @@ return array(
|
|||
'rsrc/css/application/countdown/timer.css' => 'bff8012f',
|
||||
'rsrc/css/application/daemon/bulk-job.css' => '73af99f5',
|
||||
'rsrc/css/application/dashboard/dashboard.css' => '5a205b9d',
|
||||
'rsrc/css/application/diff/diff-tree-view.css' => '26fb4a0d',
|
||||
'rsrc/css/application/diff/diff-tree-view.css' => 'e2d3e222',
|
||||
'rsrc/css/application/diff/inline-comment-summary.css' => '81eb368d',
|
||||
'rsrc/css/application/differential/add-comment.css' => '7e5900d9',
|
||||
'rsrc/css/application/differential/changeset-view.css' => '489b6995',
|
||||
|
@ -378,10 +378,10 @@ return array(
|
|||
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9',
|
||||
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8',
|
||||
'rsrc/js/application/diff/DiffChangeset.js' => 'a1a5dc46',
|
||||
'rsrc/js/application/diff/DiffChangeset.js' => 'dd1a6f34',
|
||||
'rsrc/js/application/diff/DiffChangesetList.js' => '57035863',
|
||||
'rsrc/js/application/diff/DiffInline.js' => '16e97ebc',
|
||||
'rsrc/js/application/diff/DiffPathView.js' => 'ceb66010',
|
||||
'rsrc/js/application/diff/DiffPathView.js' => '8207abf9',
|
||||
'rsrc/js/application/diff/DiffTreeView.js' => '5d83623b',
|
||||
'rsrc/js/application/diff/behavior-preview-link.js' => 'f51e9c17',
|
||||
'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd',
|
||||
|
@ -558,7 +558,7 @@ return array(
|
|||
'conpherence-thread-manager' => 'aec8e38c',
|
||||
'conpherence-transaction-css' => '3a3f5e7e',
|
||||
'd3' => '9d068042',
|
||||
'diff-tree-view-css' => '26fb4a0d',
|
||||
'diff-tree-view-css' => 'e2d3e222',
|
||||
'differential-changeset-view-css' => '489b6995',
|
||||
'differential-core-view-css' => '7300a73e',
|
||||
'differential-revision-add-comment-css' => '7e5900d9',
|
||||
|
@ -775,10 +775,10 @@ return array(
|
|||
'phabricator-darklog' => '3b869402',
|
||||
'phabricator-darkmessage' => '26cd4b73',
|
||||
'phabricator-dashboard-css' => '5a205b9d',
|
||||
'phabricator-diff-changeset' => 'a1a5dc46',
|
||||
'phabricator-diff-changeset' => 'dd1a6f34',
|
||||
'phabricator-diff-changeset-list' => '57035863',
|
||||
'phabricator-diff-inline' => '16e97ebc',
|
||||
'phabricator-diff-path-view' => 'ceb66010',
|
||||
'phabricator-diff-path-view' => '8207abf9',
|
||||
'phabricator-diff-tree-view' => '5d83623b',
|
||||
'phabricator-drag-and-drop-file-upload' => '4370900d',
|
||||
'phabricator-draggable-list' => '0169e425',
|
||||
|
@ -1645,6 +1645,9 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'8207abf9' => array(
|
||||
'javelin-dom',
|
||||
),
|
||||
83754533 => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1829,18 +1832,6 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-workflow',
|
||||
),
|
||||
'a1a5dc46' => array(
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'javelin-install',
|
||||
'javelin-workflow',
|
||||
'javelin-router',
|
||||
'javelin-behavior-device',
|
||||
'javelin-vector',
|
||||
'phabricator-diff-inline',
|
||||
'phabricator-diff-path-view',
|
||||
),
|
||||
'a241536a' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
|
@ -2079,9 +2070,6 @@ return array(
|
|||
'phuix-icon-view',
|
||||
'phabricator-busy',
|
||||
),
|
||||
'ceb66010' => array(
|
||||
'javelin-dom',
|
||||
),
|
||||
'cef53b3e' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -2120,6 +2108,18 @@ return array(
|
|||
'javelin-uri',
|
||||
'phabricator-notification',
|
||||
),
|
||||
'dd1a6f34' => array(
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'javelin-install',
|
||||
'javelin-workflow',
|
||||
'javelin-router',
|
||||
'javelin-behavior-device',
|
||||
'javelin-vector',
|
||||
'phabricator-diff-inline',
|
||||
'phabricator-diff-path-view',
|
||||
),
|
||||
'e150bd50' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
|
|
@ -195,6 +195,10 @@ final class DifferentialChangesetViewController extends DifferentialController {
|
|||
|
||||
$viewstate = $viewstate_engine->newViewStateFromRequest($request);
|
||||
|
||||
if ($viewstate->getDiscardResponse()) {
|
||||
return new AphrontAjaxResponse();
|
||||
}
|
||||
|
||||
$parser = id(new DifferentialChangesetParser())
|
||||
->setViewer($viewer)
|
||||
->setViewState($viewstate)
|
||||
|
|
|
@ -1895,6 +1895,7 @@ final class DifferentialChangesetParser extends Phobject {
|
|||
'highlight' => $viewstate->getHighlightLanguage(),
|
||||
'characterEncoding' => $viewstate->getCharacterEncoding(),
|
||||
'documentEngine' => $viewstate->getDocumentEngineKey(),
|
||||
'isHidden' => $viewstate->getHidden(),
|
||||
);
|
||||
|
||||
return id(new PhabricatorChangesetResponse())
|
||||
|
|
|
@ -60,12 +60,9 @@ final class DifferentialViewState
|
|||
$key,
|
||||
$default = null) {
|
||||
|
||||
$path_hash = $this->getChangesetPathHash($changeset);
|
||||
|
||||
$entries = idxv($this->viewState, array('changesets', $path_hash, $key));
|
||||
if (!is_array($entries)) {
|
||||
$entries = array();
|
||||
}
|
||||
$entries = $this->getChangesetPropertyEntries(
|
||||
$changeset,
|
||||
$key);
|
||||
|
||||
$entries = isort($entries, 'epoch');
|
||||
|
||||
|
@ -77,6 +74,19 @@ final class DifferentialViewState
|
|||
return idx($entry, 'value', $default);
|
||||
}
|
||||
|
||||
public function getChangesetPropertyEntries(
|
||||
DifferentialChangeset $changeset,
|
||||
$key) {
|
||||
$path_hash = $this->getChangesetPathHash($changeset);
|
||||
|
||||
$entries = idxv($this->viewState, array('changesets', $path_hash, $key));
|
||||
if (!is_array($entries)) {
|
||||
$entries = array();
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function getHasModifications() {
|
||||
return $this->hasModifications;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,10 @@ final class DiffusionDiffController extends DiffusionController {
|
|||
|
||||
$viewstate = $viewstate_engine->newViewStateFromRequest($request);
|
||||
|
||||
if ($viewstate->getDiscardResponse()) {
|
||||
return new AphrontAjaxResponse();
|
||||
}
|
||||
|
||||
$parser = id(new DifferentialChangesetParser())
|
||||
->setViewer($viewer)
|
||||
->setChangeset($changeset)
|
||||
|
|
|
@ -8,6 +8,9 @@ final class PhabricatorChangesetViewState
|
|||
private $documentEngineKey;
|
||||
private $rendererKey;
|
||||
private $defaultDeviceRendererKey;
|
||||
private $hidden;
|
||||
private $modifiedSinceHide;
|
||||
private $discardResponse;
|
||||
|
||||
public function setHighlightLanguage($highlight_language) {
|
||||
$this->highlightLanguage = $highlight_language;
|
||||
|
@ -54,4 +57,31 @@ final class PhabricatorChangesetViewState
|
|||
return $this->defaultDeviceRendererKey;
|
||||
}
|
||||
|
||||
public function setHidden($hidden) {
|
||||
$this->hidden = $hidden;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHidden() {
|
||||
return $this->hidden;
|
||||
}
|
||||
|
||||
public function setModifiedSinceHide($modified_since_hide) {
|
||||
$this->modifiedSinceHide = $modified_since_hide;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getModifiedSinceHide() {
|
||||
return $this->modifiedSinceHide;
|
||||
}
|
||||
|
||||
public function setDiscardResponse($discard_response) {
|
||||
$this->discardResponse = $discard_response;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDiscardResponse() {
|
||||
return $this->discardResponse;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,6 +60,11 @@ final class PhabricatorChangesetViewStateEngine
|
|||
$this->setChangesetProperty('renderer', $renderer);
|
||||
}
|
||||
|
||||
$hidden = $request->getStr('hidden');
|
||||
if ($hidden !== null) {
|
||||
$this->setChangesetProperty('hidden', (int)$hidden);
|
||||
}
|
||||
|
||||
$this->saveViewStateStorage();
|
||||
|
||||
$state = new PhabricatorChangesetViewState();
|
||||
|
@ -76,14 +81,21 @@ final class PhabricatorChangesetViewStateEngine
|
|||
$renderer = $this->getChangesetProperty('renderer');
|
||||
$state->setRendererKey($renderer);
|
||||
|
||||
$this->updateHiddenState($state);
|
||||
|
||||
// This is the client-selected default renderer based on viewport
|
||||
// dimensions.
|
||||
|
||||
$device_key = $request->getStr('device');
|
||||
if ($device_key !== null && strlen($device_key)) {
|
||||
if ($device_key !== null) {
|
||||
$state->setDefaultDeviceRendererKey($device_key);
|
||||
}
|
||||
|
||||
$discard_response = $request->getStr('discard');
|
||||
if ($discard_response !== null) {
|
||||
$state->setDiscardResponse(true);
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
|
@ -174,4 +186,50 @@ final class PhabricatorChangesetViewStateEngine
|
|||
unset($unguarded);
|
||||
}
|
||||
|
||||
private function updateHiddenState(PhabricatorChangesetViewState $state) {
|
||||
$is_hidden = false;
|
||||
$was_modified = false;
|
||||
|
||||
$storage = $this->getStorage();
|
||||
$changeset = $this->getChangeset();
|
||||
|
||||
$entries = $storage->getChangesetPropertyEntries($changeset, 'hidden');
|
||||
$entries = isort($entries, 'epoch');
|
||||
|
||||
if ($entries) {
|
||||
$other_phid = last_key($entries);
|
||||
$other_spec = last($entries);
|
||||
|
||||
$this_version = (int)$changeset->getDiffID();
|
||||
$other_version = (int)idx($other_spec, 'diffID');
|
||||
$other_value = (bool)idx($other_spec, 'value', false);
|
||||
|
||||
if ($other_value === false) {
|
||||
$is_hidden = false;
|
||||
} else if ($other_version >= $this_version) {
|
||||
$is_hidden = $other_value;
|
||||
} else {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$other_changeset = id(new DifferentialChangesetQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($other_phid))
|
||||
->executeOne();
|
||||
|
||||
$is_modified = false;
|
||||
if ($other_changeset) {
|
||||
if (!$changeset->hasSameEffectAs($other_changeset)) {
|
||||
$is_modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
$is_hidden = false;
|
||||
$was_modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
$state->setHidden($is_hidden);
|
||||
$state->setModifiedSinceHide($was_modified);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,6 +59,19 @@
|
|||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.diff-tree-path-hidden {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.diff-tree-path-icon-hidden,
|
||||
.diff-tree-path-hidden .diff-tree-path-icon-kind {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.diff-tree-path-hidden .diff-tree-path-icon-hidden {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.diff-tree-path-owned {
|
||||
border-left-color: {$orange};
|
||||
box-shadow: inset 2px 0 {$lightorange};
|
||||
|
|
|
@ -39,6 +39,7 @@ JX.install('DiffChangeset', {
|
|||
this._pathIconColor = data.pathIconColor;
|
||||
this._isLowImportance = data.isLowImportance;
|
||||
this._isOwned = data.isOwned;
|
||||
this._isLoading = true;
|
||||
|
||||
this._inlines = [];
|
||||
|
||||
|
@ -81,6 +82,7 @@ JX.install('DiffChangeset', {
|
|||
_pathIconColor: null,
|
||||
_isLowImportance: null,
|
||||
_isOwned: null,
|
||||
_isHidden: null,
|
||||
|
||||
getEditorURI: function() {
|
||||
return this._editorURI;
|
||||
|
@ -202,14 +204,13 @@ JX.install('DiffChangeset', {
|
|||
this._loaded = true;
|
||||
this._sequence++;
|
||||
|
||||
var params = this._getViewParameters(state);
|
||||
var pht = this.getChangesetList().getTranslations();
|
||||
|
||||
var workflow = new JX.Workflow(this._renderURI, params)
|
||||
var workflow = this._newReloadWorkflow(state)
|
||||
.setHandler(JX.bind(this, this._onresponse, this._sequence));
|
||||
|
||||
this._startContentWorkflow(workflow);
|
||||
|
||||
var pht = this.getChangesetList().getTranslations();
|
||||
|
||||
JX.DOM.setContent(
|
||||
this._getContentFrame(),
|
||||
JX.$N(
|
||||
|
@ -220,6 +221,11 @@ JX.install('DiffChangeset', {
|
|||
return this;
|
||||
},
|
||||
|
||||
_newReloadWorkflow: function(state) {
|
||||
var params = this._getViewParameters(state);
|
||||
return new JX.Workflow(this._renderURI, params);
|
||||
},
|
||||
|
||||
/**
|
||||
* Load missing context in a changeset.
|
||||
*
|
||||
|
@ -637,6 +643,15 @@ JX.install('DiffChangeset', {
|
|||
this._highlight = state.highlight;
|
||||
this._characterEncoding = state.characterEncoding;
|
||||
this._documentEngine = state.documentEngine;
|
||||
this._isHidden = state.isHidden;
|
||||
|
||||
var is_hidden = !this.isVisible();
|
||||
if (this._isHidden != is_hidden) {
|
||||
this.setVisible(!this._isHidden);
|
||||
}
|
||||
|
||||
this._isLoading = false;
|
||||
this.getPathView().setIsLoading(this._isLoading);
|
||||
},
|
||||
|
||||
_getContentFrame: function() {
|
||||
|
@ -844,7 +859,21 @@ JX.install('DiffChangeset', {
|
|||
},
|
||||
|
||||
toggleVisibility: function() {
|
||||
this._visible = !this._visible;
|
||||
this.setVisible(!this._visible);
|
||||
|
||||
var attrs = {
|
||||
hidden: this.isVisible() ? 0 : 1,
|
||||
discard: 1
|
||||
};
|
||||
|
||||
var workflow = this._newReloadWorkflow(attrs)
|
||||
.setHandler(JX.bag);
|
||||
|
||||
this._startContentWorkflow(workflow);
|
||||
},
|
||||
|
||||
setVisible: function(visible) {
|
||||
this._visible = visible;
|
||||
|
||||
var diff = JX.DOM.find(this._node, 'table', 'differential-diff');
|
||||
var undo = this._getUndoNode();
|
||||
|
@ -858,6 +887,8 @@ JX.install('DiffChangeset', {
|
|||
}
|
||||
|
||||
JX.Stratcom.invoke('resize');
|
||||
|
||||
this.getPathView().setIsHidden(!this._visible);
|
||||
},
|
||||
|
||||
isVisible: function() {
|
||||
|
@ -906,7 +937,8 @@ JX.install('DiffChangeset', {
|
|||
.setChangeset(this)
|
||||
.setPath(this._pathParts)
|
||||
.setIsLowImportance(this._isLowImportance)
|
||||
.setIsOwned(this._isOwned);
|
||||
.setIsOwned(this._isOwned)
|
||||
.setIsLoading(this._isLoading);
|
||||
|
||||
view.getIcon()
|
||||
.setIcon(this._pathIconIcon)
|
||||
|
|
|
@ -23,8 +23,10 @@ JX.install('DiffPathView', {
|
|||
_inlineNode: null,
|
||||
_isDirectory: false,
|
||||
_displayPath: null,
|
||||
_isOwned: false,
|
||||
_isLowImportance: false,
|
||||
_isOwned: false,
|
||||
_isHidden: false,
|
||||
_isLoading: false,
|
||||
|
||||
getNode: function() {
|
||||
if (!this._node) {
|
||||
|
@ -142,6 +144,24 @@ JX.install('DiffPathView', {
|
|||
return this;
|
||||
},
|
||||
|
||||
setIsHidden: function(hidden) {
|
||||
this._isHidden = hidden;
|
||||
|
||||
var node = this.getNode();
|
||||
JX.DOM.alterClass(node, 'diff-tree-path-hidden', this._isHidden);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setIsLoading: function(loading) {
|
||||
this._isLoading = loading;
|
||||
|
||||
var node = this.getNode();
|
||||
JX.DOM.alterClass(node, 'diff-tree-path-loading', this._isLoading);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_onclick: function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
return;
|
||||
|
@ -163,6 +183,7 @@ JX.install('DiffPathView', {
|
|||
|
||||
var content = [
|
||||
this.getInlineNode(),
|
||||
this._getHiddenIconNode(),
|
||||
this._getIconNode(),
|
||||
this._getPathNode(),
|
||||
];
|
||||
|
@ -186,13 +207,32 @@ JX.install('DiffPathView', {
|
|||
_getIconNode: function() {
|
||||
if (!this._iconNode) {
|
||||
var attrs = {
|
||||
className: 'diff-tree-path-icon',
|
||||
className: 'diff-tree-path-icon diff-tree-path-icon-kind',
|
||||
};
|
||||
this._iconNode = JX.$N('div', attrs, this.getIcon().getNode());
|
||||
}
|
||||
return this._iconNode;
|
||||
},
|
||||
|
||||
_getHiddenIconNode: function() {
|
||||
if (!this._hiddenIconNode) {
|
||||
var attrs = {
|
||||
className: 'diff-tree-path-icon diff-tree-path-icon-hidden',
|
||||
};
|
||||
this._hiddenIconNode =
|
||||
JX.$N('div', attrs, this._getHiddenIcon().getNode());
|
||||
}
|
||||
return this._hiddenIconNode;
|
||||
},
|
||||
|
||||
_getHiddenIcon: function() {
|
||||
if (!this._hiddenIcon) {
|
||||
this._hiddenIcon = new JX.PHUIXIconView()
|
||||
.setIcon('fa-times-circle-o');
|
||||
}
|
||||
return this._hiddenIcon;
|
||||
},
|
||||
|
||||
getInlineNode: function() {
|
||||
if (!this._inlineNode) {
|
||||
var attrs = {
|
||||
|
|
Loading…
Reference in a new issue