Skip to content

Commit

Permalink
FIXED: selection was broken when selection a tab with the same path a…
Browse files Browse the repository at this point in the history
…s the previous one

IMPROVED: tab close button only visible on active tab
CLEANED-UP: removed unsused code and moved lineEnding constant to platform.ts
  • Loading branch information
warpdesign committed Apr 30, 2019
1 parent 8101384 commit f95baa1
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 96 deletions.
23 changes: 15 additions & 8 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,6 @@ class App extends React.Component<WithNamespaces, IState> {

showDownloadsTab = () => {
this.appState.isExplorer = false;
// right now lister's selection is lost because
// switching to downloads destroys the listers
// and switching back to explorer view creates
// new listers, which in turns creates new nodes
// fixing this require a little work so meanwhile
// this correctly resets the cache's state
// TODO: do we still need to call this?
// this.appState.clearAllSelections();
}

showExplorerTab = () => {
Expand Down Expand Up @@ -412,9 +404,24 @@ class App extends React.Component<WithNamespaces, IState> {
onKeyDown={this.onShowHistory}
group={t('SHORTCUT.GROUP.ACTIVE_VIEW')}
/>
<Hotkey
global={true}
combo="mod + p"
label="view cache"
preventDefault={true}
onKeyDown={this.onDebugCache}
group={t('SHORTCUT.GROUP.ACTIVE_VIEW')}
/>
</Hotkeys>;
}

onDebugCache = () => {
let i = 0;
for (let cache of this.appState.views[0].caches) {
console.log('cache', cache.selected.length, cache.selected);
}
}

backwardHistory = () => {
const cache = this.getActiveFileCache();
if (cache) {
Expand Down
23 changes: 17 additions & 6 deletions src/components/FileTable.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as React from 'react';
import { IconName, Icon, Classes, HotkeysTarget, Hotkeys, Hotkey } from '@blueprintjs/core';
import { Column, Table, AutoSizer, Index, TableRowRenderer } from 'react-virtualized';
import { Column, Table, AutoSizer, Index } from 'react-virtualized';
import { AppState } from '../state/appState';
import { FileState } from '../state/fileState';
import { WithNamespaces, withNamespaces } from 'react-i18next';
import { inject } from 'mobx-react';
import i18next from 'i18next';
Expand Down Expand Up @@ -101,7 +100,7 @@ export class FileTableClass extends React.Component<IProps, IState> {
this.viewState = this.injected.viewState;

this.state = {
nodes: this.buildNodes(this.cache.files, false),
nodes: [],// this.buildNodes(this.cache.files, false),
selected: 0,
type: 'local',
position: -1,
Expand Down Expand Up @@ -193,16 +192,28 @@ export class FileTableClass extends React.Component<IProps, IState> {
this.disposer = reaction(
() => { return toJS(this.cache.files) },
(files: File[]) => {
this.updateNodes(files);
const cache = this.cache;
if (cache.cmd === 'cwd' || cache.history.length) {
this.updateNodes(files);
} else {
console.log('oops');
}
});
}

private isNodeSelected(name: string) {
return !!this.state.nodes.find(node => node.isSelected && node.name === name);
}

private getSelectedState(name: string) {
const cache = this.cache;

return !!cache.selected.find(file => file.fullname === name);
}

private buildNodes = (files: File[], keepSelection = false): ITableRow[] => {
console.log('** building nodes', files.length);
console.log('** building nodes', files.length, 'cmd=', this.cache.cmd, this.injected.viewState.getVisibleCacheIndex(), this.cache.selected.length, this.cache.selected);
console.log(this.injected.viewState.getVisibleCacheIndex());

return files
.sort((file1, file2) => {
Expand All @@ -216,7 +227,7 @@ export class FileTableClass extends React.Component<IProps, IState> {
})
.map((file, i) => {
const filetype = file.type;
const isSelected = keepSelection && this.isNodeSelected(file.fullname);
let isSelected = keepSelection && this.getSelectedState(file.fullname) || false;

const res: ITableRow = {
icon: file.isDir && "folder-close" || (filetype && TYPE_ICONS[filetype] || TYPE_ICONS['any']),
Expand Down
2 changes: 1 addition & 1 deletion src/components/TabList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class TabListClass extends React.Component<InjectedProps> {
<ButtonGroup fill className="tablist" alignText="center">
{
caches.map((cache, index) => {
const closeIcon = caches.length > 1 && <Icon iconSize={12} htmlTitle={t('TABS.CLOSE')} className="closetab" intent="warning" onClick={this.closeTab.bind(this, index)} icon="cross"></Icon>;
const closeIcon = cache.isVisible && caches.length > 1 && <Icon iconSize={12} htmlTitle={t('TABS.CLOSE')} className="closetab" intent="warning" onClick={this.closeTab.bind(this, index)} icon="cross"></Icon>;
return (
<Button key={"" + viewId + index} onClick={this.selectTab.bind(this, index)} title={cache.path} intent={cache.isVisible ? "primary" : "none"} rightIcon={closeIcon}>{cache.path.split('/').slice(-1)[0]}</Button>
)
Expand Down
7 changes: 0 additions & 7 deletions src/gui/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import DevTools from 'mobx-react-devtools';
import * as process from 'process';
import { remote } from 'electron';
import { ReactApp } from "../components/App";
import { I18nextProvider } from 'react-i18next';
import i18next from '../locale/i18n';
import { SettingsState } from "../state/settingsState";
import { Provider } from "mobx-react";
import { DragDropContextProvider } from 'react-dnd';
import { Client as FTPClient } from 'basic-ftp';
import * as fs from 'fs';
import * as stream from 'stream';
import HTML5Backend from 'react-dnd-html5-backend';

const Transform = stream.Transform;

declare var ENV: any;

class App {
Expand Down
76 changes: 5 additions & 71 deletions src/state/appState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import { File, FsApi, getFS, DOWNLOADS_DIR } from '../services/Fs';
import { FileState } from './fileState';
import { Batch } from '../transfers/batch';
import { clipboard } from 'electron';
import { isWin } from '../utils/platform';
import { lineEnding } from '../utils/platform';
import { TabDescriptor } from '../components/TabList';
import { ViewState } from './viewState';

const LINE_ENDING = isWin ? '\r\n' : '\n';

declare var ENV: any;

/**
Expand Down Expand Up @@ -47,17 +45,7 @@ interface TransferOptions {
*/
export class AppState {
caches: FileState[] = new Array();
// @computed get caches() {
// const arr: Array<FileState> = [];
// this.views.map(view => view.caches).forEach(caches:Array<FileState> => {
// for (cache:FileState of caches) {
// arr.push(cache);
// }
// });

// return arr;
// }
// two view per window now
// two views per window now
// we'll need to extend it if we decide
// to have multiple windows (which may or may not
// have several views)
Expand Down Expand Up @@ -90,10 +78,6 @@ export class AppState {
this.views[0].isActive = true;
for (let view of this.views) {
// get and activate the first cache for now
// const files = view.caches[0];
// if (files) {
// files.isVisible = true;
// }
view.setVisibleCache(0);
}
}
Expand Down Expand Up @@ -123,6 +107,8 @@ export class AppState {
return this.addTransfer(options)
.then(() => {
if (options.dstPath === cache.path && options.dstFsName === cache.getFS().name) {
// FIX ME: since watcher has been implemented, there's no need to reload cache
// if destination is local fs
cache.reload();
}
});
Expand Down Expand Up @@ -244,35 +230,6 @@ export class AppState {
return view.caches;
}

/**
* Sync (reload) caches which points to the same directory as srcCache
*
* @param srcCache the source cache to base the sync upon
*/
@action
syncCaches(srcCache: FileState) {
// get caches that are showing the same path
console.error('this.caches removed: we may need this one!');
this.views.map(view => view.caches).forEach(caches => {
for (let cache of caches) {
if (cache.status === 'ok' && cache !== srcCache && cache.getFS().name === srcCache.getFS().name && cache.isVisible) {
cache.reload();
}
}
});
// const caches = this.caches.filter((cache) => {
// return (cache !== srcCache &&
// cache.status === 'ok' &&
// cache.path === srcCache.path &&
// cache.getFS().name === srcCache.getFS().name
// );
// });

// for (let cache of caches) {
// cache.navHistory(0);
// };
}

@computed
get totalTransferProgress(): number {
let totalSize = 0;
Expand Down Expand Up @@ -342,11 +299,6 @@ export class AppState {
}

createView(viewId: number) {
// return {
// caches: new Array(),
// viewId: viewId,
// isActive: false
// };
return new ViewState(viewId);
}

Expand All @@ -363,12 +315,7 @@ export class AppState {
this.views[viewId] = view;
}

// const cache = new FileState(path, viewId);
view.addCache(path);
// this.caches.push(cache);
// this.views[viewId].caches.push(cache);

// return cache;
}

@action
Expand All @@ -377,19 +324,6 @@ export class AppState {
cache.selected.replace(newSelection);
}

@action
clearAllSelections() {
console.error('this.caches removed: we may need this one too!');
for (let view of this.views) {
const visibleCache = view.getVisibleCache();
visibleCache.clearSelection();
}
// for (let cache of this.caches) {
// cache.clearSelection();
// }
}

// global
@observable
clipboard: Clipboard = {
srcPath: '',
Expand All @@ -413,7 +347,7 @@ export class AppState {

if (files.length) {
const pathnames = files.map((file) => fileState.join(!filenameOnly && file.dir || '', file.fullname));
text = pathnames.join(LINE_ENDING);
text = pathnames.join(lineEnding);
clipboard.writeText(text);
}

Expand Down
7 changes: 6 additions & 1 deletion src/state/fileState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export class FileState {
@observable
status: TStatus;

cmd: string = '';

// @observable
// active = false;

Expand Down Expand Up @@ -354,12 +356,15 @@ export class FileState {
// return this.cd(path, path2, false, true);
// }
const joint = path2 ? this.api.join(path, path2) : this.api.sanityze(path);
this.cmd = 'cwd';

return this.api.cd(joint)
.then((path) => {
this.updatePath(path, skipHistory);
return this.list(path).then(() => path);
return this.list(path).then(() => { this.cmd = ''; return path });
})
.catch((error) => {
this.cmd = '';
console.log('path not valid ?', joint, 'restoring previous path');
this.setStatus('ok');
this.navHistory(0);
Expand Down
3 changes: 2 additions & 1 deletion src/state/viewState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export class ViewState {

@action
activateNextTab(index: number) {
const newActive = this.caches.length > index ? this.caches[index] : this.caches[0];
const length = this.caches.length;
const newActive = length > index ? this.caches[index] : this.caches[length - 1];
newActive.isVisible = true;
if (!newActive.history.length) {
newActive.cd(newActive.path);
Expand Down
3 changes: 2 additions & 1 deletion src/utils/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export const isMojave = isMac && ((parseInt(release().split('.')[0], 10) - 4) >=
export const isWin = platform === 'win32';
export const isLinux = platform === 'linux';
export const metaKeyCode = isMac && META_KEY || CTRL_KEY;
export const defaultFolder = ENV.NODE_ENV === 'production' ? appInstance.getPath('home') : (platform === "win32" ? appInstance.getPath('temp') : '/tmp/react-explorer');
export const defaultFolder = ENV.NODE_ENV === 'production' ? appInstance.getPath('home') : (platform === "win32" ? appInstance.getPath('temp') : '/tmp/react-explorer');
export const lineEnding = isWin ? '\r\n' : '\n';

0 comments on commit f95baa1

Please sign in to comment.