Skip to content

Commit

Permalink
feat(operations-list-extends-flow): share some common data
Browse files Browse the repository at this point in the history
  • Loading branch information
ElonH committed Jun 6, 2020
1 parent e8d6adf commit 380b46e
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 122 deletions.
80 changes: 80 additions & 0 deletions src/app/@dataflow/extra/clipboard-flow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { NothingFlow } from '../core';
import { OperationsListFlowOutItemNode } from '../rclone';
import { NavigationFlowOutNode } from './navigation-flow';

export type IManipulate = 'copy' | 'move' | 'del';

export interface ClipboardItem {
oper: IManipulate;
key: string;
srcRemote: string;
srcItem: OperationsListFlowOutItemNode;
dst?: NavigationFlowOutNode;
}

export class Clipboard {
public get values(): ClipboardItem[] {
return Array.from(this.data.values());
}

public get size(): number {
return this.data.size;
}
private data = new Map<string, ClipboardItem>();

public static genKey(remote: string, path: string) {
return JSON.stringify({ r: remote, p: path });
}

public add(
o: IManipulate,
remote: string,
row: OperationsListFlowOutItemNode,
dst?: NavigationFlowOutNode
) {
const key = Clipboard.genKey(remote, row.Path);
this.data.set(key, {
oper: o,
key,
srcItem: { ...row },
srcRemote: remote,
dst: { ...dst },
});
}

public pop(remote: string, path: string): ClipboardItem {
const key = Clipboard.genKey(remote, path);
if (!this.data.has(key)) return undefined;
const ans = this.data.get(key);
this.data.delete(key);
return ans;
}

public getManipulation(remote: string, path: string): IManipulate {
const key = Clipboard.genKey(remote, path);
if (!this.data.has(key)) return undefined;
return this.data.get(key).oper;
}

public countManipulation(o: IManipulate): number {
let cnt = 0;
this.data.forEach(x => (x.oper === o ? cnt++ : null));
return cnt;
}

public clear(...opers: IManipulate[]) {
if (opers.length === 0) this.data.clear();
else
this.values
.filter(x => opers.some(y => x.oper === y))
.forEach(x => {
this.data.delete(x.key);
});
}
}

export interface ClipboardFlowNode {
clipboard: Clipboard;
}

export abstract class ClipboardFlow extends NothingFlow<ClipboardFlowNode> {}
2 changes: 2 additions & 0 deletions src/app/@dataflow/extra/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './users-flow';
export * from './navigation-flow';
export * from './current-user-flow';
export * from './clipboard-flow';
export * from './operations-list-extends-flow';
54 changes: 54 additions & 0 deletions src/app/@dataflow/extra/operations-list-extends-flow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as moment from 'moment';
import { Observable, of } from 'rxjs';
import { getIconForFile, getIconForFolder } from 'vscode-icons-js';
import { FormatBytes } from '../../utils/format-bytes';
import { BareFlow, CombErr, NothingFlow } from '../core';
import {
OperationsListFlowInNode,
OperationsListFlowOutItemNode,
OperationsListFlowOutNode,
} from '../rclone';
import { ClipboardFlowNode, IManipulate } from './clipboard-flow';

export interface OperationsListExtendsFlowInNode
extends OperationsListFlowOutNode,
OperationsListFlowInNode,
ClipboardFlowNode {}

export interface OperationsListExtendsFlowOutItemNode extends OperationsListFlowOutItemNode {
SizeHumanReadable: string;
ModTimeHumanReadable: string;
ModTimeMoment: moment.Moment;
TypeIcon: string;
Manipulation: IManipulate;
}

export interface OperationsListExtendsFlowOutNode extends OperationsListFlowInNode {
list: OperationsListExtendsFlowOutItemNode[];
}

export abstract class OperationsListExtendsFlow extends BareFlow<
OperationsListExtendsFlowInNode,
OperationsListExtendsFlowOutNode
> {
// public prerequest$: Observable<CombErr<OperationsListExtendsFlowInNode>>;
protected request(
pre: CombErr<OperationsListExtendsFlowInNode>
): Observable<CombErr<OperationsListExtendsFlowOutNode>> {
if (pre[1].length !== 0 || pre[1].length !== 0) return pre as any;
const list = pre[0].list.map(
(item): OperationsListExtendsFlowOutItemNode => {
const ModTimeMoment = moment(item.ModTime);
return {
...item,
SizeHumanReadable: FormatBytes(item.Size),
ModTimeMoment,
ModTimeHumanReadable: ModTimeMoment.fromNow(),
Manipulation: pre[0].clipboard.getManipulation(pre[0].remote, item.Path),
TypeIcon: item.IsDir ? getIconForFolder(item.Name) : getIconForFile(item.Name),
};
}
);
return of([{ ...pre[0], list }, []]);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { API, APIDefinition, Columns, Config, DefaultConfig } from 'ngx-easy-table';
import { ClipboardItem, ClipboardService, IManipulate } from '../clipboard.service';
import { ClipboardItem, IManipulate } from '../../../../@dataflow/extra';
import { ClipboardService } from '../clipboard.service';

interface IRemotesTableItem {
remote: string;
Expand Down
3 changes: 2 additions & 1 deletion src/app/pages/manager/clipboard/clipboard.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { ClipboardService, IManipulate } from './clipboard.service';
import { IManipulate } from '../../../@dataflow/extra';
import { ClipboardService } from './clipboard.service';

@Component({
selector: 'app-manager-clipboard',
Expand Down
80 changes: 3 additions & 77 deletions src/app/pages/manager/clipboard/clipboard.service.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,8 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { mapTo } from 'rxjs/operators';
import { CombErr, NothingFlow } from '../../../@dataflow/core';
import { NavigationFlowOutNode } from '../../../@dataflow/extra';
import { OperationsListFlowOutItemNode } from '../../../@dataflow/rclone';

export type IManipulate = 'copy' | 'move' | 'del';

export interface ClipboardItem {
oper: IManipulate;
key: string;
srcRemote: string;
srcItem: OperationsListFlowOutItemNode;
dst?: NavigationFlowOutNode;
}

export class Clipboard {
public get values(): ClipboardItem[] {
return Array.from(this.data.values());
}

public get size(): number {
return this.data.size;
}
private data = new Map<string, ClipboardItem>();

public static genKey(remote: string, path: string) {
return JSON.stringify({ r: remote, p: path });
}

public add(
o: IManipulate,
remote: string,
row: OperationsListFlowOutItemNode,
dst?: NavigationFlowOutNode
) {
const key = Clipboard.genKey(remote, row.Path);
this.data.set(key, {
oper: o,
key,
srcItem: { ...row },
srcRemote: remote,
dst: { ...dst },
});
}

public pop(remote: string, path: string): ClipboardItem {
const key = Clipboard.genKey(remote, path);
if (!this.data.has(key)) return undefined;
const ans = this.data.get(key);
this.data.delete(key);
return ans;
}

public getManipulation(remote: string, path: string): IManipulate {
const key = Clipboard.genKey(remote, path);
if (!this.data.has(key)) return undefined;
return this.data.get(key).oper;
}

public countManipulation(o: IManipulate): number {
let cnt = 0;
this.data.forEach(x => (x.oper === o ? cnt++ : null));
return cnt;
}

public clear(...opers: IManipulate[]) {
if (opers.length === 0) this.data.clear();
else
this.values
.filter(x => opers.some(y => x.oper === y))
.forEach(x => {
this.data.delete(x.key);
});
}
}

export abstract class ClipboardFlow extends NothingFlow<{ clipboard: Clipboard }> {}
import { CombErr } from '../../../@dataflow/core';
import { Clipboard, ClipboardFlow, ClipboardFlowNode } from '../../../@dataflow/extra';

@Injectable({
providedIn: 'root',
Expand All @@ -93,7 +19,7 @@ export class ClipboardService extends Clipboard {
const outer = this;
this.clipboard$ = new (class extends ClipboardFlow {
public prerequest$ = outer.trigger.pipe(
mapTo<number, CombErr<{ clipboard: Clipboard }>>([{ clipboard: outer }, []])
mapTo<number, CombErr<ClipboardFlowNode>>([{ clipboard: outer }, []])
);
})();
this.clipboard$.deploy();
Expand Down
32 changes: 28 additions & 4 deletions src/app/pages/manager/fileMode/fileMode.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu
import { combineLatest, Subject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { CombErr } from '../../../@dataflow/core';
import { NavigationFlow, NavigationFlowOutNode } from '../../../@dataflow/extra';
import {
IManipulate,
NavigationFlow,
NavigationFlowOutNode,
OperationsListExtendsFlow,
OperationsListExtendsFlowInNode,
} from '../../../@dataflow/extra';
import { OperationsListFlow, OperationsListFlowInNode } from '../../../@dataflow/rclone';
import { ConnectionService } from '../../connection.service';
import { ClipboardService, IManipulate } from '../clipboard/clipboard.service';
import { ClipboardService } from '../clipboard/clipboard.service';
import { ListViewComponent } from './listView/listView.component';

@Component({
selector: 'app-manager-file-mode',
template: `
<app-manager-list-view [list$]="list$" (jump)="jump.emit($event)"> </app-manager-list-view>
<app-manager-list-view [listExtends$]="listExtends$" (jump)="jump.emit($event)">
</app-manager-list-view>
`,
styles: [],
})
Expand All @@ -23,7 +30,8 @@ export class FileModeComponent implements OnInit {
@Output() jump = new EventEmitter<NavigationFlowOutNode>();

private listTrigger = new Subject<number>();
list$: OperationsListFlow;
private list$: OperationsListFlow;
listExtends$: OperationsListExtendsFlow;

@ViewChild(ListViewComponent) listView: ListViewComponent;

Expand Down Expand Up @@ -55,6 +63,22 @@ export class FileModeComponent implements OnInit {
);
})();
this.list$.deploy();

this.listExtends$ = new (class extends OperationsListExtendsFlow {
public prerequest$ = combineLatest([
outer.list$.getSupersetOutput(),
outer.clipboard.clipboard$.getOutput(),
]).pipe(
map(
([listNode, cbNode]): CombErr<OperationsListExtendsFlowInNode> => [
{ ...listNode[0], ...cbNode[0] },
[].concat(listNode[1], cbNode[1]),
]
)
);
})();
this.listExtends$.deploy();

this.listTrigger.next(1);
}
}
47 changes: 18 additions & 29 deletions src/app/pages/manager/fileMode/listView/listView.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import {
Output,
ViewChild,
} from '@angular/core';
import * as moment from 'moment';
import { API, APIDefinition, Columns, Config, DefaultConfig } from 'ngx-easy-table';
import { combineLatest, Subscription } from 'rxjs';
import { getIconForFile, getIconForFolder } from 'vscode-icons-js';
import { NavigationFlowOutNode } from '../../../../@dataflow/extra';
import { OperationsListFlow, OperationsListFlowOutItemNode } from '../../../../@dataflow/rclone';
import { FormatBytes } from '../../../../utils/format-bytes';
import { ClipboardService, IManipulate } from '../../clipboard/clipboard.service';
import { Subscription } from 'rxjs';
import {
IManipulate,
NavigationFlowOutNode,
OperationsListExtendsFlow,
OperationsListExtendsFlowOutItemNode,
} from '../../../../@dataflow/extra';
import { OperationsListFlowOutItemNode } from '../../../../@dataflow/rclone';
import { ClipboardService } from '../../clipboard/clipboard.service';

@Component({
selector: 'app-manager-list-view',
Expand Down Expand Up @@ -81,12 +83,8 @@ export class ListViewComponent implements OnInit, OnDestroy {
{ key: 'MimeType', title: 'MIME Type', width: '17%' },
];

public data: (OperationsListFlowOutItemNode & {
public data: (OperationsListExtendsFlowOutItemNode & {
check: boolean;
SizeHumanReadable: string;
ModTimeHumanReadable: string;
ModTimeMoment: moment.Moment;
TypeIcon: string;
ManipulateIcon: string;
})[];
public checkAll = false;
Expand All @@ -97,9 +95,10 @@ export class ListViewComponent implements OnInit, OnDestroy {
@Output() jump = new EventEmitter<NavigationFlowOutNode>();
private remote: string;

@Input() list$: OperationsListFlow;
@Input() listExtends$: OperationsListExtendsFlow;

private listScrb: Subscription;

resetCurrentPage() {
this.checkAll = false; // TODO: not work around.
this.table.apiEvent({
Expand Down Expand Up @@ -152,27 +151,17 @@ export class ListViewComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.listScrb = combineLatest([
this.list$.getSupersetOutput(),
this.clipboardService.clipboard$.getOutput(),
]).subscribe(([listNode, cbNode]) => {
if (listNode[1].length !== 0 || cbNode[1].length !== 0) {
this.listScrb = this.listExtends$.getOutput().subscribe(listNode => {
if (listNode[1].length !== 0) {
this.data = undefined;
this.checkAll = false;
return;
}
this.remote = listNode[0].remote;
this.data = listNode[0].list as any;
this.data.forEach(item => {
item.check = false;
item.SizeHumanReadable = FormatBytes(item.Size);
item.ModTimeMoment = moment(item.ModTime);
item.ModTimeHumanReadable = item.ModTimeMoment.fromNow();
item.ManipulateIcon = this.manipulate2Icon(
cbNode[0].clipboard.getManipulation(this.remote, item.Path)
);
item.TypeIcon = item.IsDir
? getIconForFolder(item.Name)
: (item.TypeIcon = getIconForFile(item.Name));
this.data.forEach(x => {
x.check = false;
x.ManipulateIcon = this.manipulate2Icon(x.Manipulation);
});
this.checkAll = false;
});
Expand Down
Loading

0 comments on commit 380b46e

Please sign in to comment.