import autobind from "autobind-decorator" ; import path from "path" ; import * as React from "react" ; import { QuickSelect } from "components/modals" ; import { IDirectoryItem } from "models" ; import { IGotoProps } from "props/modals" ; import { IGotoState } from "states/modals" ; import Utils from "Utils" ; /** A Goto component for quickly searching the file system. */ class Goto extends React . Component < IGotoProps , IGotoState > { param props public constructor ( props ) { super ( props ) ; this . state = { currentDirectory : this . props . initialPath , directoryItems : [ ] , searchTerm : this . props . initialPath } ; } /**
     * Handles fetching the directory items to display after the component
     * mounts.
     */ public async componentDidMount ( ) { const nonHiddenDirectoryFolders = await this . getNonHiddenFolders ( this . state . currentDirectory ) ; this . setState ( { directoryItems : nonHiddenDirectoryFolders } as IGotoState ) ; } /**
     * Clears the quickSelectDefaultValue in state if it was not undefined.
     */ public componentDidUpdate ( ) { if ( this . state . quickSelectValue ) { this . setState ( { quickSelectValue : undefined } as IGotoState ) ; } } returns public render ( ) { return < QuickSelect isOpen = { this . props . isOpen } onClose = { this . props . onClose } initialItems = { this . renderItems ( ) } onKeyUp = { this . handleKeyUp } onSelect = { this . handleSelect } inputValue = { this . state . quickSelectValue } onUpdate = { this . handleUpdate } theme = { this . props . theme } / > ; } returns private renderItems ( ) { const shownItems = Utils . fuzzySearchItems < IDirectoryItem > ( this . state . searchTerm , this . state . directoryItems , item => item . path ) ; const defaultItem = { accessible : true , created : new Date ( ) , isDirectory : true , isHidden : false , lastModified : new Date ( ) , name : path . basename ( this . state . currentDirectory ) , path : this . state . currentDirectory } ; shownItems . unshift ( defaultItem ) ; return shownItems . map ( item => { const itemStyles = { color : ! item . accessible && this . props . theme . directoryItem . inaccessibleColour } ; return < li key = { item . path } value = { item . path } style = { itemStyles } > { item . path } < /li>; } ) ; } param event @ autobind private async handleKeyUp ( event ) { if ( event . key === "up" || event . key === "down" ) { return ; } const newPath = ( event . target as HTMLInputElement ) . value ; if ( event . key === "Backspace" && this . state . searchTerm . endsWith ( path . sep ) ) { await this . handleNavigateUp ( newPath ) ; } else if ( event . key === path . sep ) { await this . handleNavigateIn ( newPath ) ; } else { this . setState ( { searchTerm : newPath } ) ; } } param newPath private async handleNavigateUp ( newPath ) { const basePath = path . dirname ( this . state . searchTerm ) ; const nonHiddenDirectoryItems = await this . getNonHiddenFolders ( basePath ) ; this . setState ( { currentDirectory : basePath , directoryItems : nonHiddenDirectoryItems , searchTerm : newPath } ) ; } param newPath private async handleNavigateIn ( newPath ) { const strippedPath = newPath . endsWith ( path . sep ) ? newPath . substr ( 0 , newPath . lastIndexOf ( path . sep ) ) : newPath ; const directoryToNavigateInto = this . state . directoryItems . find ( item => item . path === strippedPath ) ! ; if ( ! directoryToNavigateInto . accessible ) { return ; } const nonHiddenDirectoryItems = await this . getNonHiddenFolders ( newPath ) ; this . setState ( { currentDirectory : newPath , directoryItems : nonHiddenDirectoryItems , searchTerm : newPath } ) ; } param basePath returns private async getNonHiddenFolders ( basePath ) { return this . props . directoryManager . listDirectory ( basePath , { filterCondition : item => item . isDirectory && ! item . isHidden , hideUnixStyleHiddenItems : this . props . settingsManager . settings . windows . hideUnixStyleHiddenItems } ) ; } param selectedItem @ autobind private handleSelect ( selectedItem ) { const directoryToNavigateInto = this . state . directoryItems . find ( item => item . path === selectedItem ) ! ; if ( ! directoryToNavigateInto . accessible ) { return ; } this . props . navigateTo ( selectedItem ) ; this . props . onClose ( ) ; } param selectedItem @ autobind private async handleUpdate ( selectedItem ) { const newDirectoryItems = await this . getNonHiddenFolders ( selectedItem ) ; this . setState ( { directoryItems : newDirectoryItems , quickSelectValue : `${ selectedItem }${ path . sep }` } as IGotoState ) ; } } export default Goto ;