Skip to content

Commit

Permalink
Better height strategy but element always rerender
Browse files Browse the repository at this point in the history
  • Loading branch information
fcollonval committed Sep 9, 2020
1 parent a9c4b1a commit 137fd8f
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 44 deletions.
2 changes: 2 additions & 0 deletions src/components/FileItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface IFileItemProps {
onDoubleClick: () => void;
selected?: boolean;
selectFile?: (file: Git.IStatusFile | null) => void;
style: React.CSSProperties;
}

export interface IGitMarkBoxProps {
Expand Down Expand Up @@ -95,6 +96,7 @@ export class FileItem extends React.Component<IFileItemProps> {
})
}
onDoubleClick={this.props.onDoubleClick}
style={this.props.style}
title={`${this.props.file.to}${status}`}
>
{this.props.markBox && (
Expand Down
63 changes: 46 additions & 17 deletions src/components/FileList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { Menu } from '@lumino/widgets';
import * as React from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { GitExtension } from '../model';
import { hiddenButtonStyle } from '../style/ActionButtonStyle';
import { fileListWrapperClass } from '../style/FileListStyle';
Expand Down Expand Up @@ -392,7 +393,9 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
if (this.props.settings.composite['simpleStaging']) {
return (
<div className={fileListWrapperClass}>
{this._renderSimpleStage(this.props.files)}
<AutoSizer disableWidth={true}>
{({ height }) => this._renderSimpleStage(this.props.files, height)}
</AutoSizer>
</div>
);
} else {
Expand Down Expand Up @@ -432,9 +435,15 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
className={fileListWrapperClass}
onContextMenu={event => event.preventDefault()}
>
{this._renderStaged(stagedFiles)}
{this._renderChanged(unstagedFiles)}
{this._renderUntracked(untrackedFiles)}
<AutoSizer disableWidth={true}>
{({ height }) => (
<>
{this._renderStaged(stagedFiles, height)}
{this._renderChanged(unstagedFiles, height)}
{this._renderUntracked(untrackedFiles, height)}
</>
)}
</AutoSizer>
</div>
);
}
Expand All @@ -454,18 +463,21 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
);
}

private _renderStaged(files: Git.IStatusFile[]) {
private _renderStaged(files: Git.IStatusFile[], height: number) {
const doubleClickDiff = this.props.settings.get('doubleClickDiff')
.composite as boolean;

const renderStagedRow = (file: Git.IStatusFile) => {
const renderStagedRow = (
file: Git.IStatusFile,
style: React.CSSProperties
) => {
const openFile = () => {
openListedFile(file, this.props.model);
};
const diffButton = this._createDiffButton(file, 'INDEX');
return (
<FileItem
key={file.to}
// key={file.to}
actions={
<React.Fragment>
<ActionButton
Expand Down Expand Up @@ -497,6 +509,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
: () => undefined
: openFile
}
style={style}
/>
);
};
Expand All @@ -513,26 +526,30 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
/>
}
collapsible
heading={'Staged'}
files={files}
heading={'Staged'}
height={height}
rowRenderer={renderStagedRow}
/>
);
}

private _renderChanged(files: Git.IStatusFile[]) {
private _renderChanged(files: Git.IStatusFile[], height: number) {
const doubleClickDiff = this.props.settings.get('doubleClickDiff')
.composite as boolean;
const disabled = files.length === 0;

const renderChangedRow = (file: Git.IStatusFile) => {
const renderChangedRow = (
file: Git.IStatusFile,
style: React.CSSProperties
) => {
const openFile = () => {
openListedFile(file, this.props.model);
};
const diffButton = this._createDiffButton(file, 'WORKING');
return (
<FileItem
key={file.to}
// key={file.to}
actions={
<React.Fragment>
<ActionButton
Expand Down Expand Up @@ -572,6 +589,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
: () => undefined
: openFile
}
style={style}
/>
);
};
Expand All @@ -597,20 +615,24 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
}
collapsible
heading={'Changed'}
height={height}
files={files}
rowRenderer={renderChangedRow}
/>
);
}

private _renderUntracked(files: Git.IStatusFile[]) {
private _renderUntracked(files: Git.IStatusFile[], height: number) {
const doubleClickDiff = this.props.settings.get('doubleClickDiff')
.composite as boolean;

const renderUntrackedRow = (file: Git.IStatusFile) => {
const renderUntrackedRow = (
file: Git.IStatusFile,
style: React.CSSProperties
) => {
return (
<FileItem
key={file.to}
// key={file.to}
actions={
<React.Fragment>
<ActionButton
Expand Down Expand Up @@ -641,6 +663,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
}}
selected={this._isSelectedFile(file)}
selectFile={this.updateSelectedFile}
style={style}
/>
);
};
Expand All @@ -658,17 +681,21 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
}
collapsible
heading={'Untracked'}
height={height}
files={files}
rowRenderer={renderUntrackedRow}
/>
);
}

private _renderSimpleStage(files: Git.IStatusFile[]) {
private _renderSimpleStage(files: Git.IStatusFile[], height: number) {
const doubleClickDiff = this.props.settings.get('doubleClickDiff')
.composite as boolean;

const renderSimpleStageRow = (file: Git.IStatusFile) => {
const renderSimpleStageRow = (
file: Git.IStatusFile,
style: React.CSSProperties
) => {
const openFile = () => {
openListedFile(file, this.props.model);
};
Expand Down Expand Up @@ -744,14 +771,15 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {

return (
<FileItem
key={file.to}
// key={file.to}
actions={actions}
file={file}
markBox={true}
model={this.props.model}
onDoubleClick={onDoubleClick}
contextMenu={contextMenu}
selectFile={this.updateSelectedFile}
style={style}
/>
);
};
Expand All @@ -768,6 +796,7 @@ export class FileList extends React.Component<IFileListProps, IFileListState> {
/>
}
heading={'Changed'}
height={height}
files={files}
rowRenderer={renderSimpleStageRow}
/>
Expand Down
63 changes: 37 additions & 26 deletions src/components/GitStage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { caretDownIcon, caretRightIcon } from '@jupyterlab/ui-components';
import * as React from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { FixedSizeList } from 'react-window';
import {
changeStageButtonStyle,
Expand All @@ -11,6 +10,9 @@ import {
} from '../style/GitStageStyle';
import { Git } from '../tokens';

const HEADER_HEIGHT = 34;
const ITEM_HEIGHT = 25;

/**
* Git stage component properties
*/
Expand All @@ -23,18 +25,22 @@ export interface IGitStageProps {
* Is this group collapsible
*/
collapsible?: boolean;
/**
* Group title
*/
heading: string;
/**
* Files in the group
*/
files: Git.IStatusFile[];
/**
* Group title
*/
heading: string;
height: number;
/**
* Row renderer
*/
rowRenderer: (file: Git.IStatusFile) => JSX.Element;
rowRenderer: (
file: Git.IStatusFile,
style: React.CSSProperties
) => JSX.Element;
}

/**
Expand All @@ -50,6 +56,17 @@ export const GitStage: React.FunctionComponent<IGitStageProps> = (
const [showFiles, setShowFiles] = React.useState(true);
const nFiles = props.files.length;

const _renderList = ({
index,
style
}: {
index: number;
style: React.CSSProperties;
}) => {
const file = props.files[index];
return props.rowRenderer(file, style);
};

return (
<div className={sectionFileContainerStyle}>
<div className={sectionAreaStyle}>
Expand All @@ -73,27 +90,21 @@ export const GitStage: React.FunctionComponent<IGitStageProps> = (
{props.actions}
<span className={sectionHeaderSizeStyle}>({nFiles})</span>
</div>
{showFiles && (
<AutoSizer>
{({ height, width }) => (
<FixedSizeList
height={height}
itemCount={nFiles}
itemSize={25}
width={width}
>
{({ index, style }) => {
const file = props.files[index];
return (
<div style={style} key={file.to}>
{props.rowRenderer(file)}
</div>
);
}}
</FixedSizeList>
// <ul className={sectionFileContainerStyle}></ul>
{showFiles && nFiles > 0 && (
<FixedSizeList
height={Math.max(
Math.min(props.height, nFiles * ITEM_HEIGHT) - HEADER_HEIGHT,
ITEM_HEIGHT
)}
</AutoSizer>
itemCount={nFiles}
itemData={props.files}
itemKey={(index, data) => data[index].to}
itemSize={ITEM_HEIGHT}
width={'100%'}
style={{ overflowX: 'visible' }}
>
{_renderList}
</FixedSizeList>
)}
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/style/FileItemStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const fileStyle = style(
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
boxSizing: 'border-box',
color: 'var(--jp-ui-font-color1)',
lineHeight: 'var(--jp-private-running-item-height)',
padding: '0px 4px',
Expand Down
2 changes: 1 addition & 1 deletion src/style/FileListStyle.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { style } from 'typestyle';

export const fileListWrapperClass = style({
height: 'auto',
height: 'inherit',
minHeight: '150px',

overflow: 'hidden',
Expand Down

0 comments on commit 137fd8f

Please sign in to comment.