From 4947106f000db7a1348e454d3e5410671f3725cb Mon Sep 17 00:00:00 2001 From: Frederic Collonval Date: Sat, 26 Sep 2020 19:21:32 +0200 Subject: [PATCH 1/5] Use docRegistry for file listing --- src/components/ActionButton.tsx | 2 +- src/components/FileItem.tsx | 2 +- src/components/FilePath.tsx | 30 +++++--------- src/components/SinglePastCommitInfo.tsx | 2 +- src/index.ts | 1 + src/model.ts | 30 +++++++++++++- src/style/FileItemStyle.ts | 2 +- src/style/FileListStyle.ts | 40 ------------------- src/style/FilePathStyle.ts | 4 -- src/utils.ts | 53 ------------------------- 10 files changed, 43 insertions(+), 123 deletions(-) diff --git a/src/components/ActionButton.tsx b/src/components/ActionButton.tsx index 7c7d4d7bf..9059e01b4 100644 --- a/src/components/ActionButton.tsx +++ b/src/components/ActionButton.tsx @@ -26,7 +26,7 @@ export interface IActionButtonProps { /** * On-click event handler */ - onClick?: (event?: React.MouseEvent) => void; + onClick?: (event?: React.MouseEvent) => void; } /** diff --git a/src/components/FileItem.tsx b/src/components/FileItem.tsx index be66d9c5f..5a4f126b9 100644 --- a/src/components/FileItem.tsx +++ b/src/components/FileItem.tsx @@ -185,7 +185,7 @@ export class FileItem extends React.PureComponent { )} {this.props.actions} diff --git a/src/components/FilePath.tsx b/src/components/FilePath.tsx index 1dd4af195..88f7f47a8 100644 --- a/src/components/FilePath.tsx +++ b/src/components/FilePath.tsx @@ -1,11 +1,8 @@ +import { DocumentRegistry } from '@jupyterlab/docregistry'; +import { fileIcon } from '@jupyterlab/ui-components'; import * as React from 'react'; -import { classes } from 'typestyle'; -import { - fileIconStyle, - fileLabelStyle, - folderLabelStyle -} from '../style/FilePathStyle'; -import { extractFilename, getFileIconClassName } from '../utils'; +import { fileLabelStyle, folderLabelStyle } from '../style/FilePathStyle'; +import { extractFilename } from '../utils'; /** * FilePath component properties @@ -16,13 +13,9 @@ export interface IFilePathProps { */ filepath: string; /** - * Is file selected? - impact style of the icon + * File type */ - selected?: boolean; -} - -function getFileIconClass(path: string): string { - return getFileIconClassName(path); + filetype: DocumentRegistry.IFileType; } export const FilePath: React.FunctionComponent = ( @@ -33,16 +26,11 @@ export const FilePath: React.FunctionComponent = ( .slice(0, props.filepath.length - filename.length) .replace(/^\/|\/$/g, ''); // Remove leading and trailing '/' + const icon = props.filetype.icon || fileIcon; + return ( - + {filename} {folder} diff --git a/src/components/SinglePastCommitInfo.tsx b/src/components/SinglePastCommitInfo.tsx index 95ae60999..d5d444526 100644 --- a/src/components/SinglePastCommitInfo.tsx +++ b/src/components/SinglePastCommitInfo.tsx @@ -256,7 +256,7 @@ export class SinglePastCommitInfo extends React.Component< style={style} title={path} > - + {flg ? ( ) : null} diff --git a/src/index.ts b/src/index.ts index a4408ebcd..9bfe889c3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -112,6 +112,7 @@ async function activate( gitExtension = new GitExtension( serverSettings.serverRoot, docmanager, + app.docRegistry, settings ); diff --git a/src/model.ts b/src/model.ts index 37041c703..156baa476 100644 --- a/src/model.ts +++ b/src/model.ts @@ -1,5 +1,6 @@ import { IChangedArgs, PathExt } from '@jupyterlab/coreutils'; import { IDocumentManager } from '@jupyterlab/docmanager'; +import { DocumentRegistry } from '@jupyterlab/docregistry'; import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { JSONObject } from '@lumino/coreutils'; import { Poll } from '@lumino/polling'; @@ -26,10 +27,12 @@ export class GitExtension implements IGitExtension { constructor( serverRoot: string, docmanager: IDocumentManager = null, + docRegistry: DocumentRegistry = null, settings?: ISettingRegistry.ISettings ) { this._serverRoot = serverRoot; this._docmanager = docmanager; + this._docRegistry = docRegistry; this._settings = settings || null; this._taskHandler = new TaskHandler(this); @@ -519,6 +522,11 @@ export class GitExtension implements IGitExtension { return d; } ); + + data.modified_files = data.modified_files.map(f => { + f.type = this._resolveFileType(f.modified_file_path); + return f; + }); return data; } @@ -751,7 +759,11 @@ export class GitExtension implements IGitExtension { this._setStatus( data.files.map(file => { - return { ...file, status: decodeStage(file.x, file.y) }; + return { + ...file, + status: decodeStage(file.x, file.y), + type: this._resolveFileType(file.to) + }; }) ); } catch (err) { @@ -1076,6 +1088,21 @@ export class GitExtension implements IGitExtension { return path; } + /** + * Resolve path to filetype + */ + protected _resolveFileType(path: string): DocumentRegistry.IFileType { + // test if directory + if (path.endsWith('/')) { + return DocumentRegistry.defaultDirectoryFileType; + } + + return ( + this._docRegistry.getFileTypesForPath(path)[0] || + DocumentRegistry.defaultTextFileType + ); + } + /** * Set the repository status. * @@ -1131,6 +1158,7 @@ export class GitExtension implements IGitExtension { private _currentBranch: Git.IBranch; private _serverRoot: string; private _docmanager: IDocumentManager | null; + private _docRegistry: DocumentRegistry | null; private _diffProviders: { [key: string]: Git.IDiffCallback } = {}; private _isDisposed = false; private _markerCache: Markers = new Markers(() => this._markChanged.emit()); diff --git a/src/style/FileItemStyle.ts b/src/style/FileItemStyle.ts index ecd697e95..f3a5ee04c 100644 --- a/src/style/FileItemStyle.ts +++ b/src/style/FileItemStyle.ts @@ -37,7 +37,7 @@ export const selectedFileStyle = style({ stroke: 'var(--jp-layout-color2)' }, '& .jp-icon-selectable[fill]': { - fill: '#fff' + fill: 'var(--jp-layout-color1)' }, '& .jp-icon-selectable-inverse[fill]': { fill: 'var(--jp-brand-color1)' diff --git a/src/style/FileListStyle.ts b/src/style/FileListStyle.ts index e80df39b8..2499de811 100644 --- a/src/style/FileListStyle.ts +++ b/src/style/FileListStyle.ts @@ -7,43 +7,3 @@ export const fileListWrapperClass = style({ overflow: 'hidden', overflowY: 'auto' }); - -export const notebookFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-notebook)' -}); - -export const folderFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-directory)' -}); - -export const genericFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-file)' -}); - -export const yamlFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-yaml)' -}); - -export const markdownFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-markdown)' -}); - -export const imageFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-image)' -}); - -export const spreadsheetFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-spreadsheet)' -}); - -export const jsonFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-json)' -}); - -export const pythonFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-python)' -}); - -export const rKernelFileIconStyle = style({ - backgroundImage: 'var(--jp-icon-r-kernel)' -}); diff --git a/src/style/FilePathStyle.ts b/src/style/FilePathStyle.ts index c8c0248c3..b8ed11502 100644 --- a/src/style/FilePathStyle.ts +++ b/src/style/FilePathStyle.ts @@ -1,10 +1,6 @@ import { style } from 'typestyle'; export const fileIconStyle = style({ - alignSelf: 'center', - backgroundPosition: 'center', - backgroundRepeat: 'no-repeat', - backgroundSize: '16px', flex: '0 0 auto', height: '16px', width: '16px', diff --git a/src/utils.ts b/src/utils.ts index b251bb51a..48816f029 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,16 +1,4 @@ import { PathExt } from '@jupyterlab/coreutils'; -import { - folderFileIconStyle, - genericFileIconStyle, - imageFileIconStyle, - jsonFileIconStyle, - rKernelFileIconStyle, - markdownFileIconStyle, - notebookFileIconStyle, - pythonFileIconStyle, - spreadsheetFileIconStyle, - yamlFileIconStyle -} from './style/FileListStyle'; import { Git } from './tokens'; /** Get the filename from a path */ @@ -40,47 +28,6 @@ export function decodeStage(x: string, y: string): Git.Status { return null; } -/** - * Get the extension of a given file - * - * @param path File path for which the icon should be found - */ -export function getFileIconClassName(path: string): string { - if (path[path.length - 1] === '/') { - return folderFileIconStyle; - } - const fileExtension = PathExt.extname(path).toLocaleLowerCase(); - switch (fileExtension) { - case '.md': - return markdownFileIconStyle; - case '.py': - return pythonFileIconStyle; - case '.ipynb': - return notebookFileIconStyle; - case '.json': - return jsonFileIconStyle; - case '.csv': - case '.xls': - case '.xlsx': - return spreadsheetFileIconStyle; - case '.r': - return rKernelFileIconStyle; - case '.yml': - case '.yaml': - return yamlFileIconStyle; - case '.svg': - case '.tiff': - case '.jpeg': - case '.jpg': - case '.gif': - case '.png': - case '.raw': - return imageFileIconStyle; - default: - return genericFileIconStyle; - } -} - /** * Returns a promise which resolves after a specified duration. * From 2cffe31a2aed059b4debaf2aa61ed6ced59c6423 Mon Sep 17 00:00:00 2001 From: Frederic Collonval Date: Sat, 26 Sep 2020 19:47:52 +0200 Subject: [PATCH 2/5] Vectorize branch icon --- src/components/BranchMenu.tsx | 9 ++------- src/components/NewBranchDialog.tsx | 10 ++-------- src/style/BranchMenu.ts | 15 ++++++++------- src/style/NewBranchDialog.ts | 15 ++++++++------- style/icons/branch.svg | 2 +- style/index.css | 12 ------------ style/variables.css | 2 -- 7 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/components/BranchMenu.tsx b/src/components/BranchMenu.tsx index 550a49379..4edeff9de 100644 --- a/src/components/BranchMenu.tsx +++ b/src/components/BranchMenu.tsx @@ -17,6 +17,7 @@ import { newBranchButtonClass, wrapperClass } from '../style/BranchMenu'; +import { branchIcon } from '../style/icons'; import { Git, IGitExtension, Level } from '../tokens'; import { NewBranchDialog } from './NewBranchDialog'; @@ -270,13 +271,7 @@ export class BranchMenu extends React.Component< onClick={this._onBranchClickFactory(branch.name)} style={style} > - + {branch.name} ); diff --git a/src/components/NewBranchDialog.tsx b/src/components/NewBranchDialog.tsx index bfc9c6b3c..5c2efb176 100644 --- a/src/components/NewBranchDialog.tsx +++ b/src/components/NewBranchDialog.tsx @@ -6,6 +6,7 @@ import * as React from 'react'; import { ListChildComponentProps, VariableSizeList } from 'react-window'; import { classes } from 'typestyle'; import { Logger } from '../logger'; +import { branchIcon } from '../style/icons'; import { actionsWrapperClass, activeListItemClass, @@ -313,14 +314,7 @@ export class NewBranchDialog extends React.Component< onClick={this._onBranchClickFactory(branch.name)} style={style} > - +

-