Skip to content

Commit

Permalink
Save locations, statistics, and filter collapse (#158)
Browse files Browse the repository at this point in the history
* keep track of all save locations

* show all save locations in drop-down menu

* same drop-down options when moving torrents

* toggle filters

* add statistics info in a modal

* fix some random typo
  • Loading branch information
bill-ahmed authored Dec 21, 2021
1 parent d993035 commit 6d8a318
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 13 deletions.
4 changes: 3 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import { RateLimitsDialogComponent } from './modals/rate-limits-dialog/rate-limi
import { ChipLabelComponent } from './chip-label/chip-label.component';
import { TagModule } from 'primeng/tag';
import { ContextMenuModule } from 'primeng/contextmenu';
import { StatisticsDialogComponent } from './modals/statistics-dialog/statistics-dialog.component';

var appRoutes: Routes;

Expand Down Expand Up @@ -106,7 +107,8 @@ if(!environment.production){
InfoSnackbarComponent,
DragAndDropFilesDirective,
RateLimitsDialogComponent,
ChipLabelComponent
ChipLabelComponent,
StatisticsDialogComponent
],
imports: [
CdkTreeModule,
Expand Down
27 changes: 22 additions & 5 deletions src/app/global-transfer-info/global-transfer-info.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ <h4>Toggle alt limit</h4>
</div>
</section>

<mat-divider class="spaced" [inset]="true"></mat-divider>

<button mat-stroked-button color="default" (click)="openStatisticsDialog()" style="margin: 10px;">
<mat-icon>trending_up</mat-icon> &nbsp;
<span>Statistics</span>
</button>

<mat-divider class="spaced" [inset]="true"></mat-divider>

<section id="disk_summary">
<mat-spinner diameter=30 *ngIf="isLoading()"></mat-spinner>

Expand Down Expand Up @@ -65,7 +74,7 @@ <h4>Downloaded: {{getDownloadedString()}}</h4>
<br/>
<mat-chip style="cursor: pointer;" (click)="handleUploadLimitSelect()" disableRipple matTooltip="Click to set upload limit" matTooltipPosition="below">
<mat-icon color="accent">arrow_upward</mat-icon>
<h4>some speed {{getUploadSpeedString()}} {{getUpLimitString()}}</h4>
<h4>{{getUploadSpeedString()}} {{getUpLimitString()}}</h4>
</mat-chip>

<mat-chip disableRipple>
Expand All @@ -83,9 +92,13 @@ <h3 style="margin-bottom: 5px;">
Filter
</h3>

<h4>Status</h4>
<div (click)="toggleStatus()" class="row space-between cursor-pointer">
<h4>Status</h4>
<mat-icon *ngIf="!filterStatusOpen">expand_more</mat-icon>
<mat-icon *ngIf="filterStatusOpen">expand_less</mat-icon>
</div>

<mat-chip-list chipListSelectable="true" focused="true" [selectable]="true">
<mat-chip-list *ngIf="filterStatusOpen" chipListSelectable="true" focused="true" [selectable]="true">

<mat-chip (click)="handleFilterStatusSelect('All')" [selected]="isSelected('All')">
<h4>All</h4>
Expand Down Expand Up @@ -139,9 +152,13 @@ <h4>Errored</h4>
</mat-chip-list>
<br/>

<h4>Trackers</h4>
<div (click)="toggleTrackers()" class="row space-between cursor-pointer">
<h4>Trackers</h4>
<mat-icon *ngIf="!filterTrackersOpen">expand_more</mat-icon>
<mat-icon *ngIf="filterTrackersOpen">expand_less</mat-icon>
</div>

<mat-chip-list chipListSelectable="true" focused="true" [selectable]="true">
<mat-chip-list *ngIf="filterTrackersOpen" chipListSelectable="true" focused="true" [selectable]="true">
<mat-chip style="padding: 7px; overflow: hidden; overflow-x: auto;" *ngFor="let tracker of trackerList()" (click)="handleFilterTrackerSelect(tracker)" [selected]="isSelected(tracker)">
<div class="row">
<h4 style="margin: 0; margin-right: 5px; overflow: visible;">
Expand Down
26 changes: 25 additions & 1 deletion src/app/global-transfer-info/global-transfer-info.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { RateLimitsDialogComponent } from '../modals/rate-limits-dialog/rate-lim
import { IsMobileUser } from 'src/utils/Helpers';
import { TorrentFilter, TorrentFilterService } from '../services/torrent-filter-service.service';
import { PrettyPrintTorrentDataService } from '../services/pretty-print-torrent-data.service';
import { ApplicationConfigService } from '../services/app/application-config.service';
import { StatisticsDialogComponent } from '../modals/statistics-dialog/statistics-dialog.component';

@Component({
selector: 'app-global-transfer-info',
Expand All @@ -29,9 +31,13 @@ export class GlobalTransferInfoComponent implements OnInit {
public isDarkTheme: Observable<boolean>;
public isMobileUser = IsMobileUser();

// Toggle filter views
public filterStatusOpen: boolean;
public filterTrackersOpen: boolean;

constructor(private data_store: TorrentDataStoreService, private networkInfo: NetworkConnectionInformationService, private units_helper:
UnitsHelperService, public pp: PrettyPrintTorrentDataService, private rateLimitDialog: MatDialog, private filterService: TorrentFilterService,
private theme: ThemeService) { }
private theme: ThemeService, private appConfig: ApplicationConfigService, public statisticsDialog: MatDialog) { }

ngOnInit(): void {
this.isDarkTheme = this.theme.getThemeSubscription();
Expand All @@ -49,12 +55,20 @@ export class GlobalTransferInfoComponent implements OnInit {
.subscribe(newInterval => {
this.refreshInterval = this.networkInfo.getRefreshInterval();
})

this.appConfig.getUserPreferencesSubscription().subscribe(userPref => {
this.filterStatusOpen = userPref.web_ui_options?.filters?.status_open;
this.filterTrackersOpen = userPref.web_ui_options?.filters?.tracker_open;
})
}

public toggleTheme(): void {
this.theme.setDarkTheme(!this.theme.getCurrentValue());
}

toggleStatus() { this.appConfig.toggleFilterStatusOpen() }
toggleTrackers() { this.appConfig.toggleFilterTrackersOpen() }

trackerList() {
let trackers = [];
for(let t in this.mainData?.trackers)
Expand All @@ -63,6 +77,16 @@ export class GlobalTransferInfoComponent implements OnInit {
return trackers;
}

openStatisticsDialog() {
let options: any = {
disableClose: false,
panelClass: "generic-dialog",
data: this.data
};

this.statisticsDialog.open(StatisticsDialogComponent, options)
}

handleDataChange(newData: GlobalTransferInfo): void {
this.data = newData;
this.isAltSpeedEnabled = this.data.use_alt_speed_limits;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,18 @@ <h3>Save Location</h3>
<div id="choose_save_location">
<mat-form-field appearance="outline">
<mat-label>Download To...</mat-label>
<input value="{{filesDestination}}" name="savepath" type="text" id="savepath" (change)="updateFileDestination($event)" matInput >
<input value="{{filesDestination}}" name="savepath" type="text" id="savepath" (change)="updateFileDestination($event)" matInput [matAutocomplete]="auto" >

<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of allSaveLocations" [value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</mat-form-field>

<button id="trigger_file_explorer" color="accent" mat-raised-button (click)="openFileSystemExplorerDialog($event)">
<mat-icon>folder</mat-icon>
&nbsp; Choose Location
&nbsp; Location
</button>
</div>
</mat-dialog-content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@
max-height: unset;

#choose_save_location {
width: 85%;
min-width: 300px;

display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
justify-content: space-between;
align-items: baseline;

#trigger_file_explorer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export class AddTorrentDialogComponent implements OnInit {

public isMobileUser = IsMobileUser();

public allSaveLocations: string[] = [];

/** Keep track of the mat-tab the user is currently in. */
public currentTab: MatTabChangeEvent;
private fileSystemExplorerDialogREF: MatDialogRef<FileSystemDialogComponent, any>;
Expand All @@ -50,6 +52,8 @@ export class AddTorrentDialogComponent implements OnInit {
this.updateDefaultSaveLocationFromDisk();
this.appConfig.getUserPreferences().then(pref => { this.show_torrent_contents = pref.web_ui_options.upload_torrents?.show_parsed_torrents_from_file ?? true });

this.allSaveLocations = this.data_store.GetAllSaveLocations();

if(this.inputData?.magnetURL) {
this.urlsToUpload = this.inputData.magnetURL;
this.handleTabChange({ index: 1 } as any)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ <h3>Save Location</h3>

<mat-form-field appearance="outline">
<mat-label>Move To...</mat-label>
<input value="{{filesDestination}}" name="savepath" type="text" id="savepath" (change)="updateFileDestination($event)" matInput >
<input value="{{filesDestination}}" name="savepath" type="text" id="savepath" (change)="updateFileDestination($event)" matInput [matAutocomplete]="auto" >
<mat-icon matSuffix>folder_open</mat-icon>

<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of allSaveLocations" [value]="option">
{{option}}
</mat-option>
</mat-autocomplete>
</mat-form-field>

<br/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class MoveTorrentsDialogComponent implements OnInit {
public showListofTorrents = false;
public isDarkTheme: Observable<boolean>;

public allSaveLocations: string[] = [];

private fileSystemExplorerDialogREF: MatDialogRef<FileSystemDialogComponent, any>;

constructor(public fileSystemDialog: MatDialog, private data_store: TorrentDataStoreService,
Expand All @@ -39,6 +41,8 @@ export class MoveTorrentsDialogComponent implements OnInit {
this.torrents = this.data_store.GetTorrentsByIDs(torrent_ids);
this.torrents.sort((a, b) => a.name > b.name ? 1 : -1);

this.allSaveLocations = this.data_store.GetAllSaveLocations();

this.isDarkTheme = this.theme.getThemeSubscription();
}

Expand Down
Empty file.
97 changes: 97 additions & 0 deletions src/app/modals/statistics-dialog/statistics-dialog.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<div [ngClass]="{'dark-theme': isDarkTheme | async}">
<div class="mat-dialog-inner-container mat-app-background statistics_container">
<div class="col">
<h2 mat-dialog-title>Statistics</h2>

<section>
<h4><b>User Statistics</b></h4>

<div class="stat_item">
<p>All-time upload:</p>
<p>{{ units_helper.GetFileSizeString(inputData.alltime_ul) }}</p>
</div>

<div class="stat_item">
<p>All-time download:</p>
<p>{{ units_helper.GetFileSizeString(inputData.alltime_dl) }}</p>
</div>

<div class="stat_item">
<p>All-time share ratio:</p>
<p>{{ inputData.global_ratio }}</p>
</div>

<div class="stat_item">
<p>Session waste:</p>
<p>{{ units_helper.GetFileSizeString(inputData.total_wasted_session) }}</p>
</div>

<div class="stat_item">
<p>Connected peers:</p>
<p>{{ inputData.total_peer_connections }}</p>
</div>
</section>

<section>
<h4><b>Cache Statistics</b></h4>

<div class="stat_item">
<p>Read cache hits:</p>
<p>{{ inputData.read_cache_hits }}%</p>
</div>

<div class="stat_item">
<p>Total buffer size:</p>
<p>{{ units_helper.GetFileSizeString(inputData.total_buffers_size) }}</p>
</div>
</section>

<section>
<h4><b>Performance Statistics</b></h4>

<div class="stat_item">
<p>Write cache overload:</p>
<p>{{ inputData.write_cache_overload }}%</p>
</div>

<div class="stat_item">
<p>Read cache overload:</p>
<p>{{ inputData.read_cache_overload }}%</p>
</div>

<div class="stat_item">
<p>Queued I/O jobs:</p>
<p>{{ inputData.queued_io_jobs }}</p>
</div>

<div class="stat_item">
<p>Average time in queue:</p>
<p>{{ inputData.average_time_queue }}ms</p>
</div>

<div class="stat_item">
<p>Total queued size:</p>
<p>{{ units_helper.GetFileSizeString(inputData.total_queued_size) }}</p>
</div>
</section>
</div>
</div>
</div>

<style>
.statistics_container {
width: 350px;
}

b { font-weight: 500; }
h4 { margin-bottom: 10px; }
section { margin-bottom: 5px; }

.stat_item {
display: flex;
flex-direction: row;
justify-content: space-between;

padding: 0 10px;
}
</style>
24 changes: 24 additions & 0 deletions src/app/modals/statistics-dialog/statistics-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Observable } from 'rxjs';
import { ThemeService } from 'src/app/services/theme.service';
import { UnitsHelperService } from 'src/app/services/units-helper.service';

@Component({
selector: 'app-statistics-dialog',
templateUrl: './statistics-dialog.component.html',
styleUrls: ['./statistics-dialog.component.css']
})
export class StatisticsDialogComponent implements OnInit {
public isDarkTheme: Observable<boolean>;
public inputData: any; // Data passed in to this component

constructor(private theme: ThemeService, public units_helper: UnitsHelperService, @Inject(MAT_DIALOG_DATA) inputData) {
this.inputData = inputData;
}

ngOnInit(): void {
this.isDarkTheme = this.theme.getThemeSubscription();
}

}
10 changes: 10 additions & 0 deletions src/app/services/app/application-config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ export class ApplicationConfigService {
this.user_preferences.web_ui_options.torrent_table.columns_to_show = cols;
this._persistWebUIOptions(updateNow);
}

toggleFilterStatusOpen() {
this.user_preferences.web_ui_options.filters.status_open = !this.user_preferences.web_ui_options.filters.status_open;
this._persistWebUIOptions(true)
}

toggleFilterTrackersOpen() {
this.user_preferences.web_ui_options.filters.tracker_open = !this.user_preferences.web_ui_options.filters.tracker_open;
this._persistWebUIOptions(true)
}

/**
* Update column width with change in width provided.
Expand Down
4 changes: 4 additions & 0 deletions src/app/services/app/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export class ApplicationDefaults {
upload_torrents: {
show_parsed_torrents_from_file: true,
show_parsed_torrents_from_magnet: true
},
filters: {
status_open: true,
tracker_open: false
}
}
}
Loading

0 comments on commit 6d8a318

Please sign in to comment.