Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Commit

Permalink
Automatically show and hide diagnostics panel
Browse files Browse the repository at this point in the history
Summary: Add an option to the Diagnostics preferences which allows the panel to hide or show itself automatically when messages change.

Reviewed By: matthewwithanm

Differential Revision: D6054438

fbshipit-source-id: 677524da31e143f9c5b7deb0382a41e6862971d3
  • Loading branch information
pelmers authored and hansonw committed Oct 19, 2017
1 parent 31a4e56 commit f639475
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import type {RegExpFilterChange} from 'nuclide-commons-ui/RegExpFilter';

import {goToLocation} from 'nuclide-commons-atom/go-to-location';
import nuclideUri from 'nuclide-commons/nuclideUri';
import observePaneItemVisibility from 'nuclide-commons-atom/observePaneItemVisibility';
import {arrayEqual} from 'nuclide-commons/collection';
import UniversalDisposable from 'nuclide-commons/UniversalDisposable';
import React from 'react';
import analytics from 'nuclide-commons-atom/analytics';
import Model from 'nuclide-commons/Model';
import observePaneItemVisibility from 'nuclide-commons-atom/observePaneItemVisibility';
import {renderReactRoot} from 'nuclide-commons-ui/renderReactRoot';
import {toggle} from 'nuclide-commons/observable';
import {bindObservableAsProps} from 'nuclide-commons-ui/bindObservableAsProps';
import {Observable} from 'rxjs';
import {getFilterPattern} from 'nuclide-commons-ui/RegExpFilter';
Expand Down Expand Up @@ -81,9 +81,11 @@ export class DiagnosticsViewModel {
const props = Observable.combineLatest(
globalStates,
this._model.toObservable(),
(globalState, instanceState) => ({
visibility,
(globalState, instanceState, isVisibile) => ({
...globalState,
...instanceState,
isVisibile,
diagnostics: this._filterDiagnostics(
globalState.diagnostics,
instanceState.textFilter.pattern,
Expand All @@ -97,8 +99,52 @@ export class DiagnosticsViewModel {
}),
);

// "Mute" the props stream when the view is hidden so we don't do unnecessary updates.
this._props = toggle(props, visibility);
this._props = this._trackVisibility(props);
}

// If autoVisibility setting is on, then automatically show/hide on changes.
// Otherwise mute the props stream to prevent unnecessary updates.
_trackVisibility(props: Observable<Props>): Observable<Props> {
let lastDiagnostics = [];
return props.do(newProps => {
if (
newProps.autoVisibility &&
!arrayEqual(
newProps.diagnostics,
lastDiagnostics,
(a, b) => a.text === b.text,
)
) {
if (newProps.diagnostics.length > 0) {
const activePane = atom.workspace.getActivePane();
// Do not use goToLocation because diagnostics item is not a file.
atom.workspace // eslint-disable-line
// $FlowFixMe: workspace.open accepts an item or URI
.open(this)
.then(() => {
// Since workspace.open focuses the pane containing the diagnostics,
// we manually return focus to the previously active pane.
if (activePane != null) {
// Somehow calling activate immediately does not return focus.
activePane.activate();
}
});
} else {
const pane = atom.workspace.paneForURI(WORKSPACE_VIEW_URI);
// Only hide the diagnostics if it's the only item in its pane.
if (pane != null) {
const items = pane.getItems();
if (
items.length === 1 &&
items[0] instanceof DiagnosticsViewModel
) {
atom.workspace.hide(WORKSPACE_VIEW_URI);
}
}
}
lastDiagnostics = newProps.diagnostics;
}
});
}

destroy(): void {
Expand Down
10 changes: 10 additions & 0 deletions modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ class Activation {
'atom-ide-diagnostics-ui.showDirectoryColumn',
): any);

const autoVisibilityStream: Observable<
boolean,
> = (featureConfig.observeAsStream(
'atom-ide-diagnostics-ui.autoVisibility',
): any);

const pathToActiveTextEditorStream = getActiveEditorPaths();

const filterByActiveTextEditorStream = packageStates
Expand Down Expand Up @@ -244,12 +250,14 @@ class Activation {
),
);

// $FlowFixMe: exceeds number of args defined in flow-typed definition
this._globalViewStates = Observable.combineLatest(
diagnosticsStream,
filterByActiveTextEditorStream,
pathToActiveTextEditorStream,
showTracesStream,
showDirectoryColumnStream,
autoVisibilityStream,
supportedMessageKindsStream,
uiConfigStream,
(
Expand All @@ -258,6 +266,7 @@ class Activation {
pathToActiveTextEditor,
showTraces,
showDirectoryColumn,
autoVisibility,
supportedMessageKinds,
uiConfig,
) => ({
Expand All @@ -266,6 +275,7 @@ class Activation {
pathToActiveTextEditor,
showTraces,
showDirectoryColumn,
autoVisibility,
onShowTracesChange: setShowTraces,
onFilterByActiveTextEditorChange: setFilterByActiveTextEditor,
supportedMessageKinds,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type GlobalViewState = {
filterByActiveTextEditor: boolean,
onFilterByActiveTextEditorChange: (isChecked: boolean) => mixed,
showDirectoryColumn: boolean,
autoVisibility: boolean,
showTraces: boolean,
onShowTracesChange: (isChecked: boolean) => mixed,
supportedMessageKinds: Set<DiagnosticMessageKind>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export type Props = {
selectedMessage: ?DiagnosticMessage,
supportedMessageKinds: Set<DiagnosticMessageKind>,
uiConfig: UiConfig,
isVisibile: boolean,
// Used by the DiagnosticsViewModel.
autoVisibility: boolean, // eslint-disable-line react/no-unused-prop-types

hiddenGroups: Set<DiagnosticGroup>,
onTypeFilterChange: (type: DiagnosticGroup) => mixed,
Expand All @@ -65,6 +68,10 @@ export type Props = {
export default class DiagnosticsView extends React.Component<Props> {
_table: ?DiagnosticsTable;

shouldComponentUpdate(nextProps: Props): boolean {
return nextProps.isVisibile;
}

render(): React.Element<any> {
let {diagnostics} = this.props;
const {showDirectoryColumn, showTraces} = this.props;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export default function SettingsModal(props: Props): ?React.Element<any> {
'atom-ide-diagnostics-ui.showDirectoryColumn',
)}
/>
<BoundSettingsControl
keyPath={featureConfig.formatKeyPath(
'atom-ide-diagnostics-ui.autoVisibility',
)}
/>
</section>
{hasProviderSettings ? <HR /> : null}
{props.config.map(p => <SettingsSection key={p.providerName} {...p} />)}
Expand Down
6 changes: 6 additions & 0 deletions modules/atom-ide-ui/pkg/atom-ide-diagnostics-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
"description": "The file's directory can give more context but is often unnecessary.",
"type": "boolean",
"default": false
},
"autoVisibility": {
"title": "Automatically show and hide diagnostics panel",
"description": "When new warnings appear, show the panel. When all warnings clear, hide it.",
"type": "boolean",
"default": false
}
},
"consumedServices": {
Expand Down

0 comments on commit f639475

Please sign in to comment.