Skip to content

Commit

Permalink
Fix copy symlink (#129)
Browse files Browse the repository at this point in the history
* FIXED: show error message when shell.openItem returns false
* IMPROVED: do not show dead symlink as dir
* FIXED: do not return exe filetype when mode === -1
* MOVED: test files into __tests__ subdir
* FIXED: did show 0 file length for broken symlinks
* IMPROVED: show symlink title when hovering a symlink
* FIXED: use error color for broken symlinks on selected row
* FIXED: when copying a link, copy target, not file, fixes #91
* CLEANED-UP: removed not needed promise wrappers
* ADDED: Fs.options to specify fs-specific options
* FIXED: do not refresh dest cache on local since the watcher will do it
  • Loading branch information
warpdesign committed Apr 17, 2020
1 parent 61a30dc commit 1510947
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 138 deletions.
9 changes: 7 additions & 2 deletions src/components/FileTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ interface ITableRow {
isSelected: boolean;
nodeData: File;
className: string;
title: string;
}

interface IState {
Expand Down Expand Up @@ -256,9 +257,13 @@ export class FileTableClass extends React.Component<IProps, IState> {
isSymlink: file.isSym
});

// if (file.name.match(/link/))
// debugger;

const res: ITableRow = {
icon: file.isDir && TYPE_ICONS['dir'] || (filetype && TYPE_ICONS[filetype] || TYPE_ICONS['any']),
name: file.fullname,
title: file.isSym ? `${file.fullname}${file.target}` : file.fullname,
nodeData: file,
className: classes,
isSelected: isSelected,
Expand Down Expand Up @@ -337,9 +342,9 @@ export class FileTableClass extends React.Component<IProps, IState> {
}

nameRenderer = (data: any) => {
const iconName = data.rowData.icon;
const { icon, title } = data.rowData;

return (<div className="name"><Icon icon={iconName}></Icon><span title={data.cellData} className="file-label">{data.cellData}</span></div>);
return (<div className="name"><Icon icon={icon}></Icon><span title={title} className="file-label">{data.cellData}</span></div>);
}

/*
Expand Down
8 changes: 2 additions & 6 deletions src/components/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import { reaction, IReactionDisposer } from 'mobx';
import { inject, observer } from 'mobx-react';
import { InputGroup, ControlGroup, Button, ButtonGroup, Popover, Intent, Alert, ProgressBar, Classes, HotkeysTarget, Hotkeys, Hotkey, Tooltip, Position, IHotkeysProps } from '@blueprintjs/core';
import { InputGroup, ControlGroup, Button, ButtonGroup, Popover, Intent, Alert, HotkeysTarget, Hotkeys, Hotkey, Tooltip, Position, IHotkeysProps } from '@blueprintjs/core';
import { AppState } from "../state/appState";
import { FileMenu } from "./FileMenu";
import { MakedirDialog } from "./dialogs/MakedirDialog";
Expand Down Expand Up @@ -103,9 +103,7 @@ export class ToolbarClass extends React.Component<IProps, PathInputState> {
}

private onSubmit = () => {
console.log('onSubmit');
if (this.cache.path !== this.state.path) {
console.log('onSubmit2', this.cache.cd);
this.input.blur();
const path = this.state.path;
this.cache.cd(this.state.path)
Expand Down Expand Up @@ -397,9 +395,7 @@ export class ToolbarClass extends React.Component<IProps, PathInputState> {
const { selected, history, current } = fileCache;
const { t } = this.props;

if (fileCache) {
console.log('ok', fileCache);
} else {
if (!fileCache) {
console.log('oops', fileCache);
debugger;
}
Expand Down
10 changes: 6 additions & 4 deletions src/css/filetable.css
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,16 @@
border:1px solid rgba(0,0,0,.4);
}

.tableRow.error, .tableRow.error .bp3-icon, body.bp3-dark .tableRow.error .bp3-icon{
color: rgb(160, 43, 43);
}

.tableRow.selected, .tableRow.selected .bp3-icon{
color:#fff;
}

.tableRow.error,
.tableRow.error .bp3-icon,
body.bp3-dark .tableRow.error .bp3-icon{
color: rgb(160, 43, 43);
}

/* dark theme */
body.bp3-dark .tableRow:hover{
background-color:rgba(92, 112, 128, 0.3);
Expand Down
3 changes: 2 additions & 1 deletion src/locale/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@
"EEXIST": "A file with that name already exists",
"NODEST": "copy target could not be accessed",
"COPY_ERROR": "Couldn't copy files: {{message}}",
"COPY_UNKNOWN_ERROR": "Error while copying files."
"COPY_UNKNOWN_ERROR": "Error while copying files.",
"SHELL_OPEN_FAILED": "Could not open file: {{path}}"
},
"MAIN_PROCESS": {
"PRESS_TO_EXIT": "Keep pressing ⌘Q to exit"
Expand Down
3 changes: 2 additions & 1 deletion src/locale/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@
"EEXIST": "Un fichier avec ce nom existe déjà",
"NODEST": "la destination de la copie n'est pas accessible",
"COPY_ERROR": "La copie n'a pu s'effectuer: {{message}}",
"COPY_UNKNOWN_ERROR": "Impossible de copier les fichiers demandés."
"COPY_UNKNOWN_ERROR": "Impossible de copier les fichiers demandés.",
"SHELL_OPEN_FAILED": "Impossible d'ouvrir le fichier: {{path}}"
},
"MAIN_PROCESS": {
"PRESS_TO_EXIT": "Maintenez la touche ⌘Q enfoncée pour quitter"
Expand Down
9 changes: 8 additions & 1 deletion src/services/Fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface File {
name: string;
fullname: string;
extension: string;
target: string;
cDate: Date;
mDate: Date;
bDate: Date;
Expand All @@ -50,6 +51,10 @@ export interface File {
id: FileID;
}

export interface FsOptions {
needsRefresh: boolean;
}

export interface Fs {
// runtime api
API: (new (path: string, onFsChange: (filename: string) => void) => FsApi);
Expand All @@ -61,6 +66,7 @@ export interface Fs {
name: string;
description: string;
icon: string;
options: FsOptions;
}

export const Extensions: { [index: string]: RegExp } = {
Expand Down Expand Up @@ -93,7 +99,7 @@ function isModeExe(mode: number, gid: number, uid: number): Boolean {
const isGroup = gid ? process.getgid && gid === process.getgid() : false;
const isUser = uid ? process.getuid && uid === process.getuid() : false;

return !!((mode & ExeMaskAll) || ((mode & ExeMaskUser) && isGroup) || ((mode & ExeMaskGroup) && isUser));
return !!((mode !== -1 && (mode & ExeMaskAll)) || ((mode & ExeMaskUser) && isGroup) || ((mode & ExeMaskGroup) && isUser));
}

export function filetype(mode: number, gid: number, uid: number, extension: string): FileType {
Expand Down Expand Up @@ -128,6 +134,7 @@ export interface FsApi {
isDir(path: string, transferId?: number): Promise<boolean>;
exists(path: string, transferId?: number): Promise<boolean>;
size(source: string, files: string[], transferId?: number): Promise<number>;
makeSymlink(targetPath: string, path: string, transferId?: number): Promise<boolean>;
getStream(path: string, file: string, transferId?: number): Promise<Readable>;
putStream(readStream: Readable, dstPath: string, progress: (bytesRead: number) => void, transferId?: number): Promise<void>;
getParentTree(dir: string): Array<{ dir: string, fullname: string }>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getSortMethod } from './FsSort';
import { File } from './Fs';
import { getSortMethod } from '../FsSort';
import { File } from '../Fs';

const files: Array<File> = [{
"dir": "/",
Expand All @@ -18,6 +18,7 @@ const files: Array<File> = [{
"dev": 1
},
isSym: false,
target: null,
type: ''
},
{
Expand All @@ -37,6 +38,7 @@ const files: Array<File> = [{
"dev": 1
},
isSym: false,
target: null,
type: ''
},
{
Expand All @@ -56,6 +58,7 @@ const files: Array<File> = [{
"dev": 1
},
isSym: false,
target: null,
type: ''
},
{
Expand All @@ -75,6 +78,7 @@ const files: Array<File> = [{
"dev": 1
},
isSym: false,
target: null,
type: ''
}];

Expand Down
9 changes: 9 additions & 0 deletions src/services/plugins/FsFtp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class Client {
readonly: false,
type: ftpFile.type !== 'd' && filetype(0, 0, 0, ext) || '',
isSym: false,
target: null,
id: {
ino: mDate.getTime(),
dev: new Date().getTime()
Expand Down Expand Up @@ -586,6 +587,11 @@ class FtpAPI implements FsApi {
return this.master.list(dir);
};

async makeSymlink(targetPath: string, path: string, transferId?: number): Promise<boolean> {
console.log("FsFtp.makeSymlink")
return true;
}

async stat(fullPath: string): Promise<File> {
console.warn('FsFtp.stat: TODO');
return Promise.resolve({
Expand Down Expand Up @@ -752,6 +758,9 @@ export const FsFtp: Fs = {
icon: 'globe-network',
name: 'ftp',
description: 'Fs that just implements fs over ftp',
options: {
needsRefresh: true
},
canread(str: string): boolean {
const info = new URL(str);
console.log('FsFtp.canread', str, info.protocol, info.protocol === 'ftp:');
Expand Down
8 changes: 8 additions & 0 deletions src/services/plugins/FsGeneric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class GenericApi implements FsApi {
return Promise.resolve(true);
}

async makeSymlink(targetPath: string, path: string, transferId?: number): Promise<boolean> {
console.log("FsGeneric.makeSymlink")
return true;
}

stat(fullPath: string, transferId = -1): Promise<File> {
return Promise.resolve({
dir: "",
Expand Down Expand Up @@ -139,6 +144,9 @@ export const FsGeneric: Fs = {
icon: "database",
name: "generic",
description: "Fs that just implements the FsInterface but does nothing",
options: {
needsRefresh: false
},
canread(str: string): boolean {
return true;
},
Expand Down
Loading

0 comments on commit 1510947

Please sign in to comment.