Implement category dropdown for add-new-torrent component
This commit is contained in:
parent
e2195944e4
commit
cf278e2964
3 changed files with 66 additions and 29 deletions
|
|
@ -220,26 +220,25 @@
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Category</label>
|
<label class="label">Category</label>
|
||||||
@if (categories.length > 0) {
|
<div class="control category-combo">
|
||||||
<div class="control select is-fullwidth">
|
<input
|
||||||
<select [(ngModel)]="categorySelect" (ngModelChange)="onCategorySelectChange($event)">
|
class="input"
|
||||||
<option value="">— None —</option>
|
type="text"
|
||||||
@for (cat of categories; track cat) {
|
[(ngModel)]="category"
|
||||||
<option [value]="cat">{{ cat }}</option>
|
(focus)="categoryDropdownOpen = true"
|
||||||
|
(input)="categoryDropdownOpen = true"
|
||||||
|
(blur)="onCategoryBlur()"
|
||||||
|
placeholder="Type or select a category"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
@if (categoryDropdownOpen && filteredCategories.length > 0) {
|
||||||
|
<div class="category-dropdown">
|
||||||
|
@for (cat of filteredCategories; track $index) {
|
||||||
|
<a class="category-option" (mousedown)="selectCategory(cat)">{{ cat }}</a>
|
||||||
}
|
}
|
||||||
<option value="__custom__">Custom…</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
@if (categorySelect === '__custom__') {
|
|
||||||
<div class="control" style="margin-top: 0.5rem">
|
|
||||||
<input class="input" type="text" placeholder="Enter custom category" [(ngModel)]="category" />
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
} @else {
|
</div>
|
||||||
<div class="control">
|
|
||||||
<input class="input" type="text" [(ngModel)]="category" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<p class="help">The category becomes a sub-folder in your main download path.</p>
|
<p class="help">The category becomes a sub-folder in your main download path.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,29 @@
|
||||||
.separator:not(:empty)::after {
|
.separator:not(:empty)::after {
|
||||||
margin-left: 0.25em;
|
margin-left: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.category-combo {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
width: 100%;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #dbdbdb;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-option {
|
||||||
|
display: block;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
color: #363636;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
|
|
||||||
public category: string;
|
public category: string;
|
||||||
public categories: string[] = [];
|
public categories: string[] = [];
|
||||||
public categorySelect: string = '';
|
public categoryDropdownOpen = false;
|
||||||
public hostDownloadAction: number = 0;
|
public hostDownloadAction: number = 0;
|
||||||
public downloadAction: number = 0;
|
public downloadAction: number = 0;
|
||||||
public finishedAction: number = 0;
|
public finishedAction: number = 0;
|
||||||
|
|
@ -84,11 +84,16 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
|
|
||||||
this.category = settings.find((m) => m.key === 'Gui:Default:Category')?.value as string;
|
this.category = settings.find((m) => m.key === 'Gui:Default:Category')?.value as string;
|
||||||
const categoriesSetting = settings.find((m) => m.key === 'General:Categories')?.value as string;
|
const categoriesSetting = settings.find((m) => m.key === 'General:Categories')?.value as string;
|
||||||
this.categories = (categoriesSetting ?? '').split(',').map((c) => c.trim()).filter((c) => c.length > 0);
|
this.categories = (categoriesSetting ?? '')
|
||||||
if (this.categories.includes(this.category)) {
|
.split(',')
|
||||||
this.categorySelect = this.category;
|
.map((c) => c.trim())
|
||||||
} else if (this.category) {
|
.filter((c) => c.length > 0)
|
||||||
this.categorySelect = '__custom__';
|
.filter((c, i, arr) => arr.findIndex((a) => a.toLowerCase() === c.toLowerCase()) === i);
|
||||||
|
const matchedCategory = this.categories.find(
|
||||||
|
(c) => c.toLowerCase() === (this.category ?? '').toLowerCase(),
|
||||||
|
);
|
||||||
|
if (matchedCategory) {
|
||||||
|
this.category = matchedCategory;
|
||||||
}
|
}
|
||||||
this.hostDownloadAction = this.downloadAction = settings.find((m) => m.key === 'Gui:Default:HostDownloadAction')
|
this.hostDownloadAction = this.downloadAction = settings.find((m) => m.key === 'Gui:Default:HostDownloadAction')
|
||||||
?.value as number;
|
?.value as number;
|
||||||
|
|
@ -109,12 +114,19 @@ export class AddNewTorrentComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCategorySelectChange(value: string): void {
|
get filteredCategories(): string[] {
|
||||||
if (value !== '__custom__') {
|
if (!this.category) return this.categories;
|
||||||
this.category = value;
|
const search = this.category.toLowerCase();
|
||||||
} else {
|
return this.categories.filter((c) => c.toLowerCase().includes(search));
|
||||||
this.category = '';
|
}
|
||||||
}
|
|
||||||
|
public selectCategory(cat: string): void {
|
||||||
|
this.category = cat;
|
||||||
|
this.categoryDropdownOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public onCategoryBlur(): void {
|
||||||
|
setTimeout(() => (this.categoryDropdownOpen = false), 150);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setFinishAction() {
|
public setFinishAction() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue