From e2773db65a4bf976273c434102b7e868eb0a90d8 Mon Sep 17 00:00:00 2001 From: Sean McCollum Date: Mon, 4 May 2026 10:42:17 -0700 Subject: [PATCH 1/3] make ui more mobile mobile-friendly Remove popovers and replace with question icons you have to click Replace combobox in output > Download Folder with an autocomplete --- ui/package.json | 2 +- ui/src/app/app.html | 120 ++++++++++++++++++-------------------------- ui/src/app/app.sass | 12 +++++ ui/src/app/app.ts | 41 +++++++++++---- 4 files changed, 92 insertions(+), 83 deletions(-) diff --git a/ui/package.json b/ui/package.json index 6a48bde..7e9cfef 100644 --- a/ui/package.json +++ b/ui/package.json @@ -5,7 +5,7 @@ "ng": "ng", "start": "ng serve", "build": "ng build", - "build:watch": "ng build --watch", + "build:watch": "ng build --watch --configuration development", "test": "ng test", "lint": "ng lint" }, diff --git a/ui/src/app/app.html b/ui/src/app/app.html index b2ae0db..d0ec2db 100644 --- a/ui/src/app/app.html +++ b/ui/src/app/app.html @@ -279,13 +279,12 @@
- Format + Format + placeholder="e.g. en, es, zh-Hans"> @for (lang of subtitleLanguages; track lang.id) { @@ -313,13 +311,12 @@
- Subtitle Source + Subtitle Source - } + [ngbTypeahead]="searchFolder" + [editable]="!!downloads.configuration['CREATE_CUSTOM_DIRS']" + (focus)="folderFocus$.next($any($event.target).value)" + (click)="folderClick$.next($any($event.target).value)" + #folderTypeahead="ngbTypeahead" + [disabled]="addInProgress || subscribeInProgress || downloads.loading"> +
- Custom Name Prefix + Custom Name Prefix + [disabled]="addInProgress || subscribeInProgress || downloads.loading">
@@ -411,18 +404,17 @@
+ [disabled]="addInProgress || subscribeInProgress || downloads.loading"> +
@if (splitByChapters) {
- Template + Template + (change)="chapterTemplateChanged()" [disabled]="addInProgress || subscribeInProgress || downloads.loading">
} @@ -431,28 +423,26 @@ @if (downloadType === 'video' || downloadType === 'audio') {
- Clip start + Clip start + [disabled]="addInProgress || subscribeInProgress || downloads.loading">
- Clip end + Clip end + [disabled]="addInProgress || subscribeInProgress || downloads.loading">
} @@ -461,23 +451,18 @@
-
-
- Auto Start - +
+
+ + +
- Items Limit + Items Limit + [disabled]="addInProgress || subscribeInProgress || downloads.loading">
- Subscription Check (min) + Subscription Check (min) + [disabled]="addInProgress || subscribeInProgress || downloads.loading">
- Subscription Title Filter + Subscription Title Filter + placeholder="Optional regex">
+ [disabled]="addInProgress || subscribeInProgress || downloads.loading" /> +
@@ -531,7 +513,7 @@
- Option Presets + Option Presets + [disabled]="addInProgress || subscribeInProgress || downloads.loading" />
@if (allowYtdlOptionsOverrides()) {
- Custom yt-dlp Options + Custom yt-dlp Options + [disabled]="addInProgress || subscribeInProgress || downloads.loading">
} @@ -566,7 +546,7 @@
-
Cookies
+
Cookies
@@ -574,8 +554,7 @@
- Format + Format
- Subtitle Source + Subtitle Source
- Custom Name Prefix + Custom Name Prefix -
@if (splitByChapters) {
- Template + Template
@@ -423,7 +422,7 @@ @if (downloadType === 'video' || downloadType === 'audio') {
- Clip start + Clip start
- Clip end + Clip end - - +
- Items Limit + Items Limit
- Subscription Check (min) + Subscription Check (min)
- Subscription Title Filter + Subscription Title Filter - - +
@@ -513,7 +510,7 @@
- Option Presets + Option Presets
- Custom yt-dlp Options + Custom yt-dlp Options Tools
-
Cookies
+
Cookies
@@ -915,7 +912,7 @@ Name URL - Sub. title filter + Sub. title filter Interval (min) Last checked Status diff --git a/ui/src/app/app.sass b/ui/src/app/app.sass index 7f4240f..c84d122 100644 --- a/ui/src/app/app.sass +++ b/ui/src/app/app.sass @@ -201,16 +201,12 @@ main color: var(--bs-secondary-color) margin-bottom: 0.4rem -.help-icon - cursor: pointer - opacity: 0.55 - padding: 0.25rem - margin-left: 0.25rem - font-size: 0.85em - line-height: 1 +.help-title + text-decoration: underline dotted + text-underline-offset: 0.2em + cursor: help - &:hover, &:focus - opacity: 1 + &:focus outline: none .cookie-status diff --git a/ui/src/app/app.ts b/ui/src/app/app.ts index 06c881a..d145db7 100644 --- a/ui/src/app/app.ts +++ b/ui/src/app/app.ts @@ -7,7 +7,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { NgbModule, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; import { NgSelectModule } from '@ng-select/ng-select'; -import { faTrashAlt, faCheckCircle, faTimesCircle, faRedoAlt, faSun, faMoon, faCheck, faCircleHalfStroke, faCircleQuestion, faDownload, faExternalLinkAlt, faFileImport, faFileExport, faCopy, faClock, faTachometerAlt, faSortAmountDown, faSortAmountUp, faChevronRight, faChevronDown, faUpload, faPause, faPlay } from '@fortawesome/free-solid-svg-icons'; +import { faTrashAlt, faCheckCircle, faTimesCircle, faRedoAlt, faSun, faMoon, faCheck, faCircleHalfStroke, faDownload, faExternalLinkAlt, faFileImport, faFileExport, faCopy, faClock, faTachometerAlt, faSortAmountDown, faSortAmountUp, faChevronRight, faChevronDown, faUpload, faPause, faPlay } from '@fortawesome/free-solid-svg-icons'; import { faGithub } from '@fortawesome/free-brands-svg-icons'; import { CookieService } from 'ngx-cookie-service'; import { AddDownloadPayload, DownloadsService } from './services/downloads.service'; @@ -172,7 +172,6 @@ export class App implements AfterViewInit, OnInit, OnDestroy { faMoon = faMoon; faCheck = faCheck; faCircleHalfStroke = faCircleHalfStroke; - faCircleQuestion = faCircleQuestion; faDownload = faDownload; faExternalLinkAlt = faExternalLinkAlt; faFileImport = faFileImport; From cf2d2dd46582462e23f389bbe209c1eb3bc95a2e Mon Sep 17 00:00:00 2001 From: Alex Shnitman Date: Fri, 29 May 2026 14:13:47 +0300 Subject: [PATCH 3/3] review fixes --- ui/src/app/app.html | 25 ++++++++++++++++++------- ui/src/app/app.ts | 26 -------------------------- 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/ui/src/app/app.html b/ui/src/app/app.html index 7081047..fb87050 100644 --- a/ui/src/app/app.html +++ b/ui/src/app/app.html @@ -384,7 +384,6 @@ (click)="folderClick$.next($any($event.target).value)" #folderTypeahead="ngbTypeahead" [disabled]="addInProgress || subscribeInProgress || downloads.loading"> -
@@ -450,12 +449,17 @@
-
-
- +
+ Auto Start +
@@ -500,7 +504,14 @@ - +
diff --git a/ui/src/app/app.ts b/ui/src/app/app.ts index d145db7..a10ff6e 100644 --- a/ui/src/app/app.ts +++ b/ui/src/app/app.ts @@ -104,7 +104,6 @@ export class App implements AfterViewInit, OnInit, OnDestroy { cookieUploadInProgress = false; themes: Theme[] = Themes; activeTheme: Theme | undefined; - customDirs$!: Observable; readonly folderTypeahead = viewChild('folderTypeahead'); folderFocus$ = new Subject(); folderClick$ = new Subject(); @@ -310,7 +309,6 @@ export class App implements AfterViewInit, OnInit, OnDestroy { this.getConfiguration(); this.getYtdlOptionsUpdateTime(); this.getYtdlOptionPresets(); - this.customDirs$ = this.getMatchingCustomDir(); this.setTheme(this.activeTheme!); this.colorSchemeMediaQuery.addEventListener('change', this.onColorSchemeChanged); @@ -377,13 +375,6 @@ export class App implements AfterViewInit, OnInit, OnDestroy { return this.downloads.configuration['ALLOW_YTDL_OPTIONS_OVERRIDES'] === true; } - allowCustomDir(tag: string) { - if (this.downloads.configuration['CREATE_CUSTOM_DIRS']) { - return tag; - } - return false; - } - searchFolder: OperatorFunction = (text$: Observable) => { const debouncedText$ = text$.pipe(debounceTime(150), distinctUntilChanged()); const clicksWithClosedPopup$ = this.folderClick$.pipe( @@ -404,23 +395,6 @@ export class App implements AfterViewInit, OnInit, OnDestroy { return this.downloadType === 'audio'; } - getMatchingCustomDir() : Observable { - return this.downloads.customDirsChanged.asObservable().pipe( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - map((output: any) => { - // Keep logic consistent with app/ytdl.py - if (this.isAudioType()) { - console.debug("Showing audio-specific download directories"); - return output["audio_download_dir"]; - } else { - console.debug("Showing default download directories"); - return output["download_dir"]; - } - }), - distinctUntilChanged((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr)) - ); - } - getYtdlOptionsUpdateTime() { this.downloads.ytdlOptionsChanged.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ // eslint-disable-next-line @typescript-eslint/no-explicit-any