Skip to content

Commit

Permalink
fix copy and download, move status bar items to notification
Browse files Browse the repository at this point in the history
  • Loading branch information
uniibu committed Apr 16, 2019
1 parent 91943cf commit 29239a6
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ export class FileDownloadCommandContribution implements CommandContribution {

registerCommands(registry: CommandRegistry): void {
const handler = new UriAwareCommandHandler<URI[]>(this.selectionService, this.downloadHandler(), { multi: true });
const linkHandler = new UriAwareCommandHandler<URI[]>(this.selectionService, this.downloadLinkHandler(), { multi: true });
registry.registerCommand(FileDownloadCommands.DOWNLOAD, handler);
registry.registerCommand(FileDownloadCommands.DOWNLOAD_LINK, linkHandler);
registry.registerCommand(FileDownloadCommands.UPLOAD, new FileSelection.CommandHandler(this.selectionService, {
multi: false,
isEnabled: selection => this.canUpload(selection),
Expand Down Expand Up @@ -73,16 +71,6 @@ export class FileDownloadCommandContribution implements CommandContribution {
};
}

protected downloadLinkHandler(): UriCommandHandler<URI[]> {
return {
execute: uris => this.executeLinkDownload(uris),
isEnabled: uris => this.isDownloadEnabled(uris) && document.queryCommandSupported('copy'),
isVisible: uris => this.isDownloadVisible(uris) && document.queryCommandSupported('copy'),
};
}
protected async executeLinkDownload(uris: URI[]): Promise<void> {
this.downloadService.copyDownloadLink(uris);
}
protected async executeDownload(uris: URI[]): Promise<void> {
this.downloadService.download(uris);
}
Expand All @@ -105,12 +93,6 @@ export namespace FileDownloadCommands {
label: 'Download'
};

export const DOWNLOAD_LINK: Command = {
id: 'file.download.link',
category: 'File',
label: 'Copy Download Link'
};

export const UPLOAD: Command = {
id: 'file.upload',
category: 'File',
Expand Down
94 changes: 38 additions & 56 deletions packages/filesystem/src/browser/download/file-download-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import { FileSystem } from '../../common/filesystem';
import { FileDownloadData } from '../../common/download/file-download-data';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { MessageService } from '@theia/core/lib/common/message-service';
import { addClipboardListener } from '@theia/core/lib/browser/widgets';
import { DisposableCollection } from '@theia/core/lib/common';

@injectable()
export class FileDownloadService {

protected static PREPARING_DOWNLOAD_ID = 'theia-preparing-download';
protected statusBarTimeout: number | undefined;
protected anchor: HTMLAnchorElement | undefined;
protected downloadQueue: number[] = [];
protected downloadCounter: number = 0;

@inject(ILogger)
Expand All @@ -46,6 +47,8 @@ export class FileDownloadService {
@inject(MessageService)
protected readonly messageService: MessageService;

protected readonly toDispose = new DisposableCollection();

protected uploadForm: {
target: HTMLInputElement
file: HTMLInputElement
Expand Down Expand Up @@ -147,77 +150,56 @@ export class FileDownloadService {
return this.deferredUpload.promise;
}

async copyDownloadLink(uris: URI[]): Promise<void> {
if (uris.length === 0) {
return;
}
try {
await this.statusBar.setElement(FileDownloadService.PREPARING_DOWNLOAD_ID, {
alignment: StatusBarAlignment.RIGHT,
text: '$(spinner~spin) Preparing download link...',
tooltip: 'Preparing download link...',
priority: 1
});
const response = await fetch(this.request(uris));
const jsonResponse = await response.json();
const { status, statusText } = response;
await this.statusBar.removeElement(FileDownloadService.PREPARING_DOWNLOAD_ID);
if (status === 200) {
const url = `${this.endpoint()}/download/?id=${jsonResponse.id}`;
const setClipBoardData = (event: ClipboardEvent) => {
event.clipboardData.setData('text/plain', url);
event.preventDefault();
};
document.addEventListener('copy', setClipBoardData);
document.execCommand('copy', false);
document.removeEventListener('copy', setClipBoardData);
this.showStatusMessage('Download link copied!', 5000, 'Download link successfully copied!');
} else {
throw new Error(`Received unexpected status code: ${status}. [${statusText}]`);
}
} catch (e) {
this.logger.error(`Error occurred when getting the download link: ${uris.map(u => u.toString(true))}.`, e);
protected handleCopy(event: ClipboardEvent, downloadUrl: string) {
if (downloadUrl) {
event.clipboardData.setData('text/plain', downloadUrl);
event.preventDefault();
this.messageService.info('Download link copied!');
}
}
async cancelDownload(id: string) {
await fetch(`${this.endpoint()}/download/?id=${id}&cancel=true`);
}

async download(uris: URI[]): Promise<void> {
let cancel = false;
if (uris.length === 0) {
return;
}
let downloadId: number | undefined;
try {
downloadId = this.downloadCounter++;
if (this.downloadQueue.length === 0) {
await this.statusBar.setElement(FileDownloadService.PREPARING_DOWNLOAD_ID, {
alignment: StatusBarAlignment.RIGHT,
text: '$(spinner~spin) Preparing download...',
tooltip: 'Preparing download...',
priority: 1
});
}
this.downloadQueue.push(downloadId);
const response = await fetch(this.request(uris));
const [progress, response] = await Promise.all([
this.messageService.showProgress({
text: 'Preparing download link...', options: { cancelable: true }
}, () => { cancel = true; }),
fetch(this.request(uris))
]);
const jsonResponse = await response.json();
await this.statusBar.removeElement(FileDownloadService.PREPARING_DOWNLOAD_ID);
if (cancel) {
this.cancelDownload(jsonResponse.id);
return;
}
const { status, statusText } = response;
if (status === 200) {
this.forceDownload(jsonResponse.id, decodeURIComponent(jsonResponse.name));
this.showStatusMessage('Download started...', 2000);
progress.cancel();
const downloadUrl = `${this.endpoint()}/download/?id=${jsonResponse.id}`;
this.messageService.info(downloadUrl, 'Download', 'Copy Download Link').then(action => {
if (action === 'Download') {
this.forceDownload(jsonResponse.id, decodeURIComponent(jsonResponse.name));
this.messageService.info('Download started!');
} else if (action === 'Copy Download Link') {
if (document.documentElement) {
addClipboardListener(document.documentElement, 'copy', e => this.handleCopy(e, downloadUrl));
document.execCommand('copy');
}
} else {
this.cancelDownload(jsonResponse.id);
}
});
} else {
throw new Error(`Received unexpected status code: ${status}. [${statusText}]`);
}
} catch (e) {
this.logger.error(`Error occurred when downloading: ${uris.map(u => u.toString(true))}.`, e);
} finally {
if (downloadId !== undefined) {
const indexOf = this.downloadQueue.indexOf(downloadId);
if (indexOf !== -1) {
this.downloadQueue.splice(indexOf, 1);
}
if (this.downloadQueue.length === 0) {
this.statusBar.removeElement(FileDownloadService.PREPARING_DOWNLOAD_ID);
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export class DownloadHandler extends FileDownloadHandler {
this.handleError(response, `Cannot access the 'id' query from the request. The query was: ${JSON.stringify(query)}.`, BAD_REQUEST);
return;
}
const cancelDownload = query.cancel;
const downloadInfo = this.fileDownloadCollection.getDownload(query.id);
if (!downloadInfo) {
this.handleError(response, `Cannot find the file from the request. The query was: ${JSON.stringify(query)}.`, NOT_FOUND);
Expand All @@ -175,9 +176,13 @@ export class DownloadHandler extends FileDownloadHandler {
response.status(OK).end();
return;
}
if (downloadInfo && downloadInfo.file) {
if (downloadInfo && downloadInfo.file && !cancelDownload) {
this.download(request, response, downloadInfo, query.id);
}
if (cancelDownload) {
this.logger.info('Download', query.id, 'has been cancelled');
this.fileDownloadCollection.deleteDownload(query.id);
}
}
}

Expand Down
4 changes: 0 additions & 4 deletions packages/navigator/src/browser/navigator-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,6 @@ export class FileNavigatorContribution extends AbstractViewContribution<FileNavi
commandId: FileDownloadCommands.DOWNLOAD.id,
order: 'b'
});
registry.registerMenuAction(downloadUploadMenu, {
commandId: FileDownloadCommands.DOWNLOAD_LINK.id,
order: 'c'
});

registry.registerMenuAction(NavigatorContextMenu.NAVIGATION, {
commandId: WorkspaceCommands.NEW_FILE.id
Expand Down
4 changes: 0 additions & 4 deletions packages/workspace/src/browser/workspace-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,6 @@ export class FileMenuContribution implements MenuContribution {
commandId: FileDownloadCommands.DOWNLOAD.id,
order: 'b'
});
registry.registerMenuAction(downloadUploadMenu, {
commandId: FileDownloadCommands.DOWNLOAD_LINK.id,
order: 'c'
});

}

Expand Down

0 comments on commit 29239a6

Please sign in to comment.