mirror of
https://github.com/Eugeny/tabby.git
synced 2025-10-05 06:24:56 +00:00
added experimental SFTP implementation - fixes #296
This commit is contained in:
@@ -88,6 +88,21 @@ export abstract class PlatformService {
|
||||
abstract startDownload (name: string, size: number): Promise<FileDownload|null>
|
||||
abstract startUpload (options?: FileUploadOptions): Promise<FileUpload[]>
|
||||
|
||||
startUploadFromDragEvent (event: DragEvent): FileUpload[] {
|
||||
const result: FileUpload[] = []
|
||||
if (!event.dataTransfer) {
|
||||
return []
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||
for (let i = 0; i < event.dataTransfer.files.length; i++) {
|
||||
const file = event.dataTransfer.files[i]
|
||||
const transfer = new DropUpload(file)
|
||||
this.fileTransferStarted.next(transfer)
|
||||
result.push(transfer)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
getConfigPath (): string|null {
|
||||
return null
|
||||
}
|
||||
@@ -144,3 +159,36 @@ export abstract class PlatformService {
|
||||
abstract showMessageBox (options: MessageBoxOptions): Promise<MessageBoxResult>
|
||||
abstract quit (): void
|
||||
}
|
||||
|
||||
|
||||
class DropUpload extends FileUpload {
|
||||
private stream: ReadableStream
|
||||
private reader: ReadableStreamDefaultReader
|
||||
|
||||
constructor (private file: File) {
|
||||
super()
|
||||
this.stream = this.file.stream()
|
||||
this.reader = this.stream.getReader()
|
||||
}
|
||||
|
||||
getName (): string {
|
||||
return this.file.name
|
||||
}
|
||||
|
||||
getSize (): number {
|
||||
return this.file.size
|
||||
}
|
||||
|
||||
async read (): Promise<Buffer> {
|
||||
const result: any = await this.reader.read()
|
||||
if (result.done || !result.value) {
|
||||
return Buffer.from('')
|
||||
}
|
||||
const chunk = Buffer.from(result.value)
|
||||
this.increaseProgress(chunk.length)
|
||||
return chunk
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
close (): void { }
|
||||
}
|
||||
|
1
terminus-core/src/directives/dropZone.directive.pug
Normal file
1
terminus-core/src/directives/dropZone.directive.pug
Normal file
@@ -0,0 +1 @@
|
||||
i.fas.fa-upload
|
24
terminus-core/src/directives/dropZone.directive.scss
Normal file
24
terminus-core/src/directives/dropZone.directive.scss
Normal file
@@ -0,0 +1,24 @@
|
||||
.drop-zone-hint {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
transition: .25s opacity ease-out;
|
||||
opacity: 0;
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 48px;
|
||||
align-self: center;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
49
terminus-core/src/directives/dropZone.directive.ts
Normal file
49
terminus-core/src/directives/dropZone.directive.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Directive, Output, ElementRef, EventEmitter, AfterViewInit } from '@angular/core'
|
||||
import { FileUpload, PlatformService } from '../api/platform'
|
||||
import './dropZone.directive.scss'
|
||||
|
||||
/** @hidden */
|
||||
@Directive({
|
||||
selector: '[dropZone]',
|
||||
})
|
||||
export class DropZoneDirective implements AfterViewInit {
|
||||
@Output() transfer = new EventEmitter<FileUpload>()
|
||||
private dropHint?: HTMLElement
|
||||
|
||||
constructor (
|
||||
private el: ElementRef,
|
||||
private platform: PlatformService,
|
||||
) { }
|
||||
|
||||
ngAfterViewInit (): void {
|
||||
this.el.nativeElement.addEventListener('dragover', () => {
|
||||
if (!this.dropHint) {
|
||||
this.dropHint = document.createElement('div')
|
||||
this.dropHint.className = 'drop-zone-hint'
|
||||
this.dropHint.innerHTML = require('./dropZone.directive.pug')
|
||||
this.el.nativeElement.appendChild(this.dropHint)
|
||||
setTimeout(() => {
|
||||
this.dropHint!.classList.add('visible')
|
||||
})
|
||||
}
|
||||
})
|
||||
this.el.nativeElement.addEventListener('drop', (event: DragEvent) => {
|
||||
this.removeHint()
|
||||
for (const transfer of this.platform.startUploadFromDragEvent(event)) {
|
||||
this.transfer.emit(transfer)
|
||||
}
|
||||
})
|
||||
this.el.nativeElement.addEventListener('dragleave', () => {
|
||||
this.removeHint()
|
||||
})
|
||||
}
|
||||
|
||||
private removeHint () {
|
||||
const element = this.dropHint
|
||||
delete this.dropHint
|
||||
element?.classList.remove('visible')
|
||||
setTimeout(() => {
|
||||
element?.remove()
|
||||
}, 500)
|
||||
}
|
||||
}
|
@@ -25,6 +25,7 @@ import { TransfersMenuComponent } from './components/transfersMenu.component'
|
||||
|
||||
import { AutofocusDirective } from './directives/autofocus.directive'
|
||||
import { FastHtmlBindDirective } from './directives/fastHtmlBind.directive'
|
||||
import { DropZoneDirective } from './directives/dropZone.directive'
|
||||
|
||||
import { Theme, CLIHandler, TabContextMenuItemProvider, TabRecoveryProvider, HotkeyProvider, ConfigProvider } from './api'
|
||||
|
||||
@@ -83,6 +84,7 @@ const PROVIDERS = [
|
||||
UnlockVaultModalComponent,
|
||||
WelcomeTabComponent,
|
||||
TransfersMenuComponent,
|
||||
DropZoneDirective,
|
||||
],
|
||||
entryComponents: [
|
||||
RenameTabModalComponent,
|
||||
@@ -96,6 +98,7 @@ const PROVIDERS = [
|
||||
CheckboxComponent,
|
||||
ToggleComponent,
|
||||
AutofocusDirective,
|
||||
DropZoneDirective,
|
||||
],
|
||||
})
|
||||
export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||
|
@@ -38,7 +38,7 @@ $theme-colors: (
|
||||
warning: $orange,
|
||||
danger: $red,
|
||||
light: $gray-300,
|
||||
dark: $gray-800,
|
||||
dark: #0e151d,
|
||||
rare: $purple
|
||||
);
|
||||
|
||||
@@ -150,7 +150,7 @@ $navbar-padding-x: 0;
|
||||
$dropdown-bg: $content-bg-solid;
|
||||
$dropdown-color: $body-color;
|
||||
$dropdown-border-width: 1px;
|
||||
$dropdown-box-shadow: 0 .5rem 1rem rgba($black,.175);
|
||||
$dropdown-box-shadow: 0 0 1rem rgba($black, .25), 0 1px 1px rgba($black, .12);
|
||||
$dropdown-header-color: $gray-500;
|
||||
|
||||
$dropdown-link-color: $body-color;
|
||||
|
Reference in New Issue
Block a user