mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-27 20:45:12 +00:00
Rework device and folder service to have public obseravble
to accomaccommodatemodate many subscribers without re-requesting data from the API
This commit is contained in:
parent
24a637e9e6
commit
ae776ff8df
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, ViewChild, Input } from '@angular/core';
|
import { Component, OnInit, ViewChild, Input, Type } from '@angular/core';
|
||||||
import Folder from '../../folder'
|
import Folder from '../../folder'
|
||||||
import { FolderService } from 'src/app/services/folder.service';
|
import { FolderService } from 'src/app/services/folder.service';
|
||||||
import { DonutChartComponent } from '../donut-chart/donut-chart.component';
|
import { DonutChartComponent } from '../donut-chart/donut-chart.component';
|
||||||
@ -6,6 +6,7 @@ import { DeviceService } from 'src/app/services/device.service';
|
|||||||
import Device from 'src/app/device';
|
import Device from 'src/app/device';
|
||||||
import { StType } from '../../type';
|
import { StType } from '../../type';
|
||||||
import { FilterService } from 'src/app/services/filter.service';
|
import { FilterService } from 'src/app/services/filter.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
|
||||||
export interface ChartItemState {
|
export interface ChartItemState {
|
||||||
@ -27,12 +28,12 @@ export class ChartComponent implements OnInit {
|
|||||||
chartID: string;
|
chartID: string;
|
||||||
states: ChartItemState[] = [];
|
states: ChartItemState[] = [];
|
||||||
|
|
||||||
private service: any;
|
private observer: Observable<any>;
|
||||||
private activeChartState: ChartItemState;
|
private activeChartState: ChartItemState;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private folderService: FolderService,
|
private folderService: FolderService,
|
||||||
private deviceServce: DeviceService,
|
private deviceService: DeviceService,
|
||||||
private filterService: FilterService,
|
private filterService: FilterService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@ -60,19 +61,19 @@ export class ChartComponent implements OnInit {
|
|||||||
case StType.Folder:
|
case StType.Folder:
|
||||||
this.title = "Folders";
|
this.title = "Folders";
|
||||||
this.chartID = 'foldersChart';
|
this.chartID = 'foldersChart';
|
||||||
this.service = this.folderService;
|
this.observer = this.folderService.folderAdded$;
|
||||||
break;
|
break;
|
||||||
case StType.Device:
|
case StType.Device:
|
||||||
this.title = "Devices";
|
this.title = "Devices";
|
||||||
this.chartID = 'devicesChart';
|
this.chartID = 'devicesChart';
|
||||||
this.service = this.deviceServce;
|
this.observer = this.deviceService.deviceAdded$;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
let totalCount: number = 0;
|
let totalCount: number = 0;
|
||||||
this.service.getEach().subscribe(
|
this.observer.subscribe(
|
||||||
t => {
|
t => {
|
||||||
// Count the number of folders and set chart
|
// Count the number of folders and set chart
|
||||||
totalCount++;
|
totalCount++;
|
||||||
|
@ -14,6 +14,8 @@ import { MatProgressBar } from '@angular/material/progress-bar';
|
|||||||
import { MessageService } from '../services/message.service';
|
import { MessageService } from '../services/message.service';
|
||||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { DialogComponent } from '../dialog/dialog.component';
|
import { DialogComponent } from '../dialog/dialog.component';
|
||||||
|
import { FolderService } from '../services/folder.service';
|
||||||
|
import { DeviceService } from '../services/device.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dashboard',
|
selector: 'app-dashboard',
|
||||||
@ -64,16 +66,21 @@ export class DashboardComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private systemConfigService: SystemConfigService,
|
private systemConfigService: SystemConfigService,
|
||||||
|
private folderService: FolderService,
|
||||||
|
private deviceService: DeviceService,
|
||||||
private progressService: ProgressService,
|
private progressService: ProgressService,
|
||||||
private messageService: MessageService,
|
private messageService: MessageService,
|
||||||
public dialog: MatDialog
|
public dialog: MatDialog
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
// Request data from Rest API
|
||||||
this.systemConfigService.getSystemConfig().subscribe(
|
this.systemConfigService.getSystemConfig().subscribe(
|
||||||
x => console.log('Observer got a next value: ' + x),
|
_ => {
|
||||||
err => console.error('Observer got an error: ' + err),
|
// Request devices and folders for charts and lists
|
||||||
() => console.log('Observer got a complete notification')
|
this.folderService.requestFolders();
|
||||||
|
this.deviceService.requestDevices();
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import { SystemConfigService } from '../../services/system-config.service';
|
|||||||
import { FilterService } from 'src/app/services/filter.service';
|
import { FilterService } from 'src/app/services/filter.service';
|
||||||
import { StType } from 'src/app/type';
|
import { StType } from 'src/app/type';
|
||||||
import { MatInput } from '@angular/material/input';
|
import { MatInput } from '@angular/material/input';
|
||||||
|
import { DeviceService } from 'src/app/services/device.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-device-list',
|
selector: 'app-device-list',
|
||||||
@ -22,10 +23,10 @@ export class DeviceListComponent implements AfterViewInit, OnInit, OnDestroy {
|
|||||||
dataSource: MatTableDataSource<Device>;
|
dataSource: MatTableDataSource<Device>;
|
||||||
|
|
||||||
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||||
displayedColumns = ['id', 'name', 'state'];
|
displayedColumns = ['id', 'name', 'state', 'folders'];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private systemConfigService: SystemConfigService,
|
private deviceService: DeviceService,
|
||||||
private filterService: FilterService,
|
private filterService: FilterService,
|
||||||
private cdr: ChangeDetectorRef,
|
private cdr: ChangeDetectorRef,
|
||||||
) { };
|
) { };
|
||||||
@ -41,9 +42,19 @@ export class DeviceListComponent implements AfterViewInit, OnInit, OnDestroy {
|
|||||||
this.dataSource = new MatTableDataSource();
|
this.dataSource = new MatTableDataSource();
|
||||||
this.dataSource.data = [];
|
this.dataSource.data = [];
|
||||||
|
|
||||||
this.systemConfigService.getDevices().subscribe(
|
// Replace all data when requests are finished
|
||||||
data => {
|
this.deviceService.devicesUpdated$.subscribe(
|
||||||
this.dataSource.data = data;
|
devices => {
|
||||||
|
this.dataSource.data = devices;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add device as they come in
|
||||||
|
let devices: Device[] = [];
|
||||||
|
this.deviceService.deviceAdded$.subscribe(
|
||||||
|
device => {
|
||||||
|
devices.push(device);
|
||||||
|
this.dataSource.data = devices;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ export class FolderListComponent implements AfterViewInit, OnInit, OnDestroy {
|
|||||||
displayedColumns = ['id', 'label', 'path', 'state'];
|
displayedColumns = ['id', 'label', 'path', 'state'];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private systemConfigService: SystemConfigService,
|
private folderService: FolderService,
|
||||||
private filterService: FilterService,
|
private filterService: FilterService,
|
||||||
private cdr: ChangeDetectorRef,
|
private cdr: ChangeDetectorRef,
|
||||||
) {
|
) {
|
||||||
@ -41,11 +41,21 @@ export class FolderListComponent implements AfterViewInit, OnInit, OnDestroy {
|
|||||||
this.dataSource = new MatTableDataSource();
|
this.dataSource = new MatTableDataSource();
|
||||||
this.dataSource.data = [];
|
this.dataSource.data = [];
|
||||||
|
|
||||||
this.systemConfigService.getFolders().subscribe(
|
// Replace all data when requests are finished
|
||||||
data => {
|
this.folderService.foldersUpdated$.subscribe(
|
||||||
this.dataSource.data = data;
|
folders => {
|
||||||
|
this.dataSource.data = folders;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add device as they come in
|
||||||
|
let folders: Folder[] = [];
|
||||||
|
this.folderService.folderAdded$.subscribe(
|
||||||
|
folder => {
|
||||||
|
folders.push(folder);
|
||||||
|
this.dataSource.data = folders;
|
||||||
|
}
|
||||||
|
);;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import Device from '../device';
|
import Device from '../device';
|
||||||
import { Observable, Subscriber } from 'rxjs';
|
import { Observable, Subscriber, ReplaySubject, Subject } from 'rxjs';
|
||||||
import { SystemConfigService } from './system-config.service';
|
import { SystemConfigService } from './system-config.service';
|
||||||
import { SystemConnectionsService } from './system-connections.service';
|
import { SystemConnectionsService } from './system-connections.service';
|
||||||
import { DbCompletionService } from './db-completion.service';
|
import { DbCompletionService } from './db-completion.service';
|
||||||
@ -15,7 +15,12 @@ import { StType } from '../type';
|
|||||||
export class DeviceService {
|
export class DeviceService {
|
||||||
private devices: Device[];
|
private devices: Device[];
|
||||||
private sysConns: SystemConnections;
|
private sysConns: SystemConnections;
|
||||||
thisDevice: Device;
|
private devicesSubject: ReplaySubject<Device[]> = new ReplaySubject(1);
|
||||||
|
devicesUpdated$ = this.devicesSubject.asObservable();
|
||||||
|
private thisDevice: Device;
|
||||||
|
|
||||||
|
private deviceAddedSource = new Subject<Device>();
|
||||||
|
deviceAdded$ = this.deviceAddedSource.asObservable();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private systemConfigService: SystemConfigService,
|
private systemConfigService: SystemConfigService,
|
||||||
@ -25,10 +30,12 @@ export class DeviceService {
|
|||||||
private progressService: ProgressService,
|
private progressService: ProgressService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
getDeviceStatusInOrder(observer: Subscriber<Device>, startIndex: number) {
|
getDeviceStatusInOrder(startIndex: number) {
|
||||||
// Return if there aren't any device at the index
|
// Return if there aren't any device at the index
|
||||||
if (startIndex >= (this.devices.length)) {
|
if (startIndex >= (this.devices.length)) {
|
||||||
observer.complete();
|
this.devicesSubject.next(this.devices);
|
||||||
|
// this.devicesSubject.complete();
|
||||||
|
// this.deviceAddedSource.complete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const device: Device = this.devices[startIndex];
|
const device: Device = this.devices[startIndex];
|
||||||
@ -53,76 +60,73 @@ export class DeviceService {
|
|||||||
Device.recalcCompletion(device);
|
Device.recalcCompletion(device);
|
||||||
device.stateType = Device.getStateType(device);
|
device.stateType = Device.getStateType(device);
|
||||||
device.state = Device.stateTypeToString(device.stateType);
|
device.state = Device.stateTypeToString(device.stateType);
|
||||||
observer.next(device);
|
|
||||||
|
|
||||||
|
this.deviceAddedSource.next(device);
|
||||||
this.progressService.addToProgress(1);
|
this.progressService.addToProgress(1);
|
||||||
|
|
||||||
// recursively get the status of the next device
|
// recursively get the status of the next device
|
||||||
this.getDeviceStatusInOrder(observer, startIndex);
|
this.getDeviceStatusInOrder(startIndex);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getEach() returns each device
|
* getEach() returns each device
|
||||||
*/
|
*/
|
||||||
getEach(): Observable<Device> {
|
requestDevices() {
|
||||||
const deviceObservable: Observable<Device> = new Observable((observer) => {
|
this.systemConfigService.getDevices().subscribe(
|
||||||
// TODO return devices if cached
|
devices => {
|
||||||
|
this.devices = devices;
|
||||||
|
|
||||||
this.systemConfigService.getDevices().subscribe(
|
// First check to see which device is local 'thisDevice'
|
||||||
devices => {
|
this.systemStatusService.getSystemStatus().subscribe(
|
||||||
this.devices = devices;
|
status => {
|
||||||
|
this.devices.forEach(device => {
|
||||||
|
if (device.deviceID === status.myID) {
|
||||||
|
// TODO Determine if it should ignore thisDevice
|
||||||
|
this.thisDevice = device;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// First check to see which device is local 'thisDevice'
|
// Check folder devices to see if the device is used
|
||||||
this.systemStatusService.getSystemStatus().subscribe(
|
this.systemConfigService.getFolders().subscribe(
|
||||||
status => {
|
folders => {
|
||||||
this.devices.forEach(device => {
|
// Loop through all folder devices to see if the device is used
|
||||||
if (device.deviceID === status.myID) {
|
this.devices.forEach(device => {
|
||||||
// TODO Determine if it should ignore thisDevice
|
// Alloc array if needed
|
||||||
this.thisDevice = device;
|
if (!device.folders) {
|
||||||
}
|
device.folders = [];
|
||||||
});
|
device.folderNames = [];
|
||||||
|
}
|
||||||
|
|
||||||
// Check folder devices to see if the device is used
|
folders.forEach(folder => {
|
||||||
this.systemConfigService.getFolders().subscribe(
|
folder.devices.forEach(fdevice => {
|
||||||
folders => {
|
if (device.deviceID === fdevice.deviceID) {
|
||||||
// Loop through all folder devices to see if the device is used
|
// The device is used by a folder
|
||||||
this.devices.forEach(device => {
|
device.used = true;
|
||||||
// Alloc array if needed
|
|
||||||
if (!device.folders) {
|
|
||||||
device.folders = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
folders.forEach(folder => {
|
// Add a reference to the folder to the device
|
||||||
folder.devices.forEach(fdevice => {
|
device.folders.push(folder);
|
||||||
if (device.deviceID === fdevice.deviceID) {
|
|
||||||
// The device is used by a folder
|
|
||||||
device.used = true;
|
|
||||||
|
|
||||||
// Add a reference to the folder to the device
|
// Add string folder name
|
||||||
device.folders.push(folder);
|
device.folderNames.push(folder.label);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// See if the connection is connected or undefined
|
|
||||||
this.systemConnectionsService.getSystemConnections().subscribe(
|
|
||||||
c => {
|
|
||||||
this.sysConns = c;
|
|
||||||
|
|
||||||
// Synchronously get the status of each device
|
|
||||||
this.getDeviceStatusInOrder(observer, 0);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
)
|
// See if the connection is connected or undefined
|
||||||
},
|
this.systemConnectionsService.getSystemConnections().subscribe(
|
||||||
err => { console.log("getEach error!", err) },
|
c => {
|
||||||
() => { console.log("getEach complete!") }
|
this.sysConns = c;
|
||||||
);
|
|
||||||
});
|
// Synchronously get the status of each device
|
||||||
return deviceObservable
|
this.getDeviceStatusInOrder(0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { SystemConfigService } from './system-config.service';
|
import { SystemConfigService } from './system-config.service';
|
||||||
import { Observable, Subscriber } from 'rxjs';
|
import { Observable, Subscriber, Subject, ReplaySubject } from 'rxjs';
|
||||||
import Folder from '../folder';
|
import Folder from '../folder';
|
||||||
import { DbStatusService } from './db-status.service';
|
import { DbStatusService } from './db-status.service';
|
||||||
import { ProgressService } from './progress.service';
|
import { ProgressService } from './progress.service';
|
||||||
@ -12,6 +12,10 @@ import { StType } from '../type';
|
|||||||
})
|
})
|
||||||
export class FolderService {
|
export class FolderService {
|
||||||
private folders: Folder[];
|
private folders: Folder[];
|
||||||
|
private foldersSubject: ReplaySubject<Folder[]> = new ReplaySubject(1);
|
||||||
|
foldersUpdated$ = this.foldersSubject.asObservable();
|
||||||
|
private folderAddedSource = new Subject<Folder>();
|
||||||
|
folderAdded$ = this.folderAddedSource.asObservable();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private systemConfigService: SystemConfigService,
|
private systemConfigService: SystemConfigService,
|
||||||
@ -20,10 +24,11 @@ export class FolderService {
|
|||||||
private progressService: ProgressService,
|
private progressService: ProgressService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
getFolderStatusInOrder(observer: Subscriber<Folder>, startIndex: number) {
|
getFolderStatusInOrder(startIndex: number) {
|
||||||
// Return if there aren't any folders at the index
|
// Return if there aren't any folders at the index
|
||||||
if (startIndex >= (this.folders.length)) {
|
if (startIndex >= (this.folders.length)) {
|
||||||
observer.complete();
|
this.foldersSubject.next(this.folders);
|
||||||
|
// this.folderAddedSource.complete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const folder: Folder = this.folders[startIndex];
|
const folder: Folder = this.folders[startIndex];
|
||||||
@ -37,37 +42,31 @@ export class FolderService {
|
|||||||
folder.completion = c;
|
folder.completion = c;
|
||||||
folder.stateType = Folder.getStateType(folder);
|
folder.stateType = Folder.getStateType(folder);
|
||||||
folder.state = Folder.stateTypeToString(folder.stateType);
|
folder.state = Folder.stateTypeToString(folder.stateType);
|
||||||
observer.next(folder);
|
|
||||||
|
|
||||||
|
this.folderAddedSource.next(folder);
|
||||||
this.progressService.addToProgress(1);
|
this.progressService.addToProgress(1);
|
||||||
|
|
||||||
// recursively get the status of the next folder
|
// recursively get the status of the next folder
|
||||||
this.getFolderStatusInOrder(observer, startIndex);
|
this.getFolderStatusInOrder(startIndex);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getEach() returns each folder and uses db status service to
|
* requestFolders() requests each folder and uses db status service to
|
||||||
* set all their statuses and db completion service to find
|
* set all their statuses and db completion service to find
|
||||||
* completion
|
* completion in order. Updating folderAdded$ and foldersUpdate$
|
||||||
|
* observers
|
||||||
*/
|
*/
|
||||||
getEach(): Observable<Folder> {
|
requestFolders() {
|
||||||
// TODO return this.folders if cached
|
this.systemConfigService.getFolders().subscribe(
|
||||||
|
folders => {
|
||||||
|
this.folders = folders;
|
||||||
|
|
||||||
const folderObservable: Observable<Folder> = new Observable((observer) => {
|
// Synchronously get the status of each folder
|
||||||
this.systemConfigService.getFolders().subscribe(
|
this.getFolderStatusInOrder(0);
|
||||||
folders => {
|
}
|
||||||
this.folders = folders;
|
);
|
||||||
|
|
||||||
// Synchronously get the status of each folder
|
|
||||||
this.getFolderStatusInOrder(observer, 0);
|
|
||||||
},
|
|
||||||
err => { console.log("getEach error!", err) },
|
|
||||||
() => { console.log("getEach complete!") }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
return folderObservable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user