Skip to content

Commit

Permalink
Fix some open file/folder issues
Browse files Browse the repository at this point in the history
- "Open folder" now says "open folder" instead of "open file"
- "Open folder" won't allow you to open files
- "Open file" won't allow you to open directories

Fixes #249.
  • Loading branch information
code-asher committed Apr 11, 2019
1 parent 2785e22 commit 7047be8
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 13 deletions.
8 changes: 7 additions & 1 deletion packages/server/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,13 @@ const bold = (text: string | number): string | number => {
const webpackConfig = require(path.resolve(__dirname, "..", "..", "web", "webpack.config.js"));
const compiler = require("webpack")(webpackConfig);
app.use(require("webpack-dev-middleware")(compiler, {
logger,
logger: {
trace: (m: string): void => logger.trace("webpack", field("message", m)),
debug: (m: string): void => logger.debug("webpack", field("message", m)),
info: (m: string): void => logger.info("webpack", field("message", m)),
warn: (m: string): void => logger.warn("webpack", field("message", m)),
error: (m: string): void => logger.error("webpack", field("message", m)),
},
publicPath: webpackConfig.output.publicPath,
stats: webpackConfig.stats,
}));
Expand Down
12 changes: 12 additions & 0 deletions packages/vscode/src/dialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
--primary: #2A2E37;
--border: black;
--faded: #a0a1a5;
--disabled: #888;
--header-background: #161616;
--header-foreground: white;
--list-active-selection-background: rgb(0, 120, 160);
Expand Down Expand Up @@ -101,6 +102,12 @@
background-color: var(--list-active-selection-background);
color: var(--list-active-selection-foreground);
}

&.disabled, &.disabled:hover {
background-color: var(--primary);
color: var(--disabled);
cursor: initial;
}
}
}

Expand Down Expand Up @@ -134,6 +141,11 @@
color: white;
}
}

button[disabled], button[disabled]:hover {
color: var(--disabled);
cursor: initial;
}
}
}

Expand Down
51 changes: 47 additions & 4 deletions packages/vscode/src/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { IThemeService } from "vs/platform/theme/common/themeService";
import { workbench } from "./workbench";
import "./dialog.scss";

/**
* Describes the type of dialog to show.
*/
export enum DialogType {
NewFolder,
Save,
Expand Down Expand Up @@ -68,8 +71,12 @@ interface DialogEntry {
readonly isDirectory: boolean;
readonly size: number;
readonly lastModified: string;
readonly isDisabled?: boolean;
}

/**
* Open and save dialogs.
*/
class Dialog {
private _path: string | undefined;

Expand Down Expand Up @@ -265,8 +272,7 @@ class Dialog {
}
if (element.isDirectory) {
this.path = element.fullPath;
} else {
// Open
} else if (!(this.options as OpenDialogOptions).properties.openDirectory) {
this.selectEmitter.emit(element.fullPath);
}
});
Expand All @@ -282,12 +288,18 @@ class Dialog {
});
buttonsNode.appendChild(cancelBtn);
const confirmBtn = document.createElement("button");
confirmBtn.innerText = "Confirm";
const openFile = (this.options as OpenDialogOptions).properties.openFile;
confirmBtn.innerText = openFile ? "Open" : "Confirm";
confirmBtn.addEventListener("click", () => {
if (this._path) {
if (this._path && !openFile) {
this.selectEmitter.emit(this._path);
}
});
// Since a single click opens a file, the only time this button can be
// used is on a directory, which is invalid for opening files.
if (openFile) {
confirmBtn.disabled = true;
}
buttonsNode.appendChild(confirmBtn);
this.root.appendChild(buttonsNode);
this.entryList.layout();
Expand All @@ -303,13 +315,19 @@ class Dialog {
return this.errorEmitter.event;
}

/**
* Remove the dialog.
*/
public dispose(): void {
this.selectEmitter.dispose();
this.errorEmitter.dispose();
this.entryList.dispose();
this.background.remove();
}

/**
* Build and insert the path shown at the top of the dialog.
*/
private buildPath(): void {
while (this.pathNode.lastChild) {
this.pathNode.removeChild(this.pathNode.lastChild);
Expand Down Expand Up @@ -376,6 +394,9 @@ class Dialog {
return (<any>this.entryList).typeFilterController.filter._pattern;
}

/**
* List the files and return dialog entries.
*/
private async list(directory: string): Promise<ReadonlyArray<DialogEntry>> {
const paths = (await util.promisify(fs.readdir)(directory)).sort();
const stats = await Promise.all(paths.map(p => util.promisify(fs.stat)(path.join(directory, p))));
Expand All @@ -386,6 +407,8 @@ class Dialog {
isDirectory: stat.isDirectory(),
lastModified: stat.mtime.toDateString(),
size: stat.size,
// If we are opening a directory, show files as disabled.
isDisabled: !stat.isDirectory() && (this.options as OpenDialogOptions).properties.openDirectory,
}));
}
}
Expand All @@ -397,11 +420,17 @@ interface DialogEntryData {
label: HighlightedLabel;
}

/**
* Rendering for the different parts of a dialog entry.
*/
class DialogEntryRenderer implements ITreeRenderer<DialogEntry, string, DialogEntryData> {
public get templateId(): string {
return "dialog-entry";
}

/**
* Append and return containers for each part of the dialog entry.
*/
public renderTemplate(container: HTMLElement): DialogEntryData {
addClass(container, "dialog-entry");
addClass(container, "dialog-grid");
Expand All @@ -422,6 +451,9 @@ class DialogEntryRenderer implements ITreeRenderer<DialogEntry, string, DialogEn
};
}

/**
* Render a dialog entry.
*/
public renderElement(node: ITreeNode<DialogEntry, string>, _index: number, templateData: DialogEntryData): void {
templateData.icon.className = "dialog-entry-icon monaco-icon-label";
const classes = getIconClasses(
Expand All @@ -444,8 +476,19 @@ class DialogEntryRenderer implements ITreeRenderer<DialogEntry, string, DialogEn
}] : []);
templateData.size.innerText = node.element.size.toString();
templateData.lastModified.innerText = node.element.lastModified;

// We know this exists because we created the template.
const entryContainer = templateData.label.element.parentElement!.parentElement!.parentElement!;
if (node.element.isDisabled) {
entryContainer.classList.add("disabled");
} else {
entryContainer.classList.remove("disabled");
}
}

/**
* Does nothing (not implemented).
*/
public disposeTemplate(_templateData: DialogEntryData): void {
// throw new Error("Method not implemented.");
}
Expand Down
22 changes: 14 additions & 8 deletions packages/vscode/src/fill/windowsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export class WindowsService implements IWindowsService {
private readonly window = new electron.BrowserWindow();

// Dialogs
public async pickFileFolderAndOpen(_options: INativeOpenDialogOptions): Promise<void> {
public async pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
showOpenDialog({
...(_options.dialogOptions || {}),
...(options.dialogOptions || {}),
properties: {
openFile: true,
openDirectory: true,
Expand All @@ -66,9 +66,9 @@ export class WindowsService implements IWindowsService {
});
}

public async pickFileAndOpen(_options: INativeOpenDialogOptions): Promise<void> {
public async pickFileAndOpen(options: INativeOpenDialogOptions): Promise<void> {
showOpenDialog({
...(_options.dialogOptions || {}),
...(options.dialogOptions || {}),
properties: {
openFile: true,
},
Expand All @@ -84,9 +84,15 @@ export class WindowsService implements IWindowsService {
});
}

public async pickFolderAndOpen(_options: INativeOpenDialogOptions): Promise<void> {
public async pickFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
if (!options.dialogOptions) {
options.dialogOptions = {};
}
if (!options.dialogOptions.title) {
options.dialogOptions.title = "Open Folder";
}
showOpenDialog({
...(_options.dialogOptions || {}),
...(options.dialogOptions || {}),
properties: {
openDirectory: true,
},
Expand All @@ -97,9 +103,9 @@ export class WindowsService implements IWindowsService {
});
}

public async pickWorkspaceAndOpen(_options: INativeOpenDialogOptions): Promise<void> {
public async pickWorkspaceAndOpen(options: INativeOpenDialogOptions): Promise<void> {
showOpenDialog({
...(_options.dialogOptions || {}),
...(options.dialogOptions || {}),
properties: {
openDirectory: true,
},
Expand Down

0 comments on commit 7047be8

Please sign in to comment.