From b1ed63a8151aacebb949e5eb8c521ad4f6198cd4 Mon Sep 17 00:00:00 2001 From: voc0der Date: Tue, 24 Feb 2026 17:05:54 -0500 Subject: [PATCH] Make app init subscriptions one-shot --- .../custom-playlists/custom-playlists.component.ts | 9 ++++----- .../components/downloads/downloads.component.ts | 9 ++++----- src/app/components/login/login.component.ts | 9 +++++---- .../notifications/notifications.component.ts | 9 ++++----- .../recent-videos/recent-videos.component.ts | 11 +++++------ src/app/components/tasks/tasks.component.ts | 9 ++++----- src/app/main/main.component.ts | 9 ++++----- src/app/player/player.component.ts | 14 ++++++++------ src/app/posts.services.ts | 5 ++++- src/app/settings/settings.component.ts | 9 +++++---- .../subscription/subscription.component.ts | 9 +++++---- 11 files changed, 52 insertions(+), 50 deletions(-) diff --git a/src/app/components/custom-playlists/custom-playlists.component.ts b/src/app/components/custom-playlists/custom-playlists.component.ts index 9fd4e04..0812623 100644 --- a/src/app/components/custom-playlists/custom-playlists.component.ts +++ b/src/app/components/custom-playlists/custom-playlists.component.ts @@ -5,6 +5,7 @@ import { MatDialog } from '@angular/material/dialog'; import { CreatePlaylistComponent } from 'app/create-playlist/create-playlist.component'; import { Playlist } from 'api-types'; import { saveAs } from 'file-saver'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-custom-playlists', @@ -21,11 +22,9 @@ export class CustomPlaylistsComponent implements OnInit { constructor(public postsService: PostsService, private router: Router, private dialog: MatDialog) { } ngOnInit(): void { - this.postsService.service_initialized.subscribe(init => { - if (init) { - this.getAllPlaylists(); - } - }); + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.getAllPlaylists()); this.postsService.playlists_changed.subscribe(changed => { if (changed) { diff --git a/src/app/components/downloads/downloads.component.ts b/src/app/components/downloads/downloads.component.ts index 57db16f..1341e39 100644 --- a/src/app/components/downloads/downloads.component.ts +++ b/src/app/components/downloads/downloads.component.ts @@ -9,6 +9,7 @@ import { ConfirmDialogComponent } from 'app/dialogs/confirm-dialog/confirm-dialo import { MatSort } from '@angular/material/sort'; import { Clipboard } from '@angular/cdk/clipboard'; import { Download } from 'api-types'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-downloads', @@ -120,11 +121,9 @@ export class DownloadsComponent implements OnInit, OnDestroy { if (this.postsService.initialized) { this.getCurrentDownloadsRecurring(); } else { - this.postsService.service_initialized.subscribe(init => { - if (init) { - this.getCurrentDownloadsRecurring(); - } - }); + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.getCurrentDownloadsRecurring()); } } diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts index 3ea2e52..06bf073 100644 --- a/src/app/components/login/login.component.ts +++ b/src/app/components/login/login.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { PostsService } from 'app/posts.services'; import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-login', @@ -31,14 +32,14 @@ export class LoginComponent implements OnInit { if (this.postsService.isLoggedIn && localStorage.getItem('jwt_token') !== 'null') { this.router.navigate(['/home']); } - this.postsService.service_initialized.subscribe(init => { - if (init) { + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => { if (!this.postsService.config['Advanced']['multi_user_mode']) { this.router.navigate(['/home']); } this.registrationEnabled = this.postsService.config['Users'] && this.postsService.config['Users']['allow_registration']; - } - }); + }); } login() { diff --git a/src/app/components/notifications/notifications.component.ts b/src/app/components/notifications/notifications.component.ts index 8456311..53782cb 100644 --- a/src/app/components/notifications/notifications.component.ts +++ b/src/app/components/notifications/notifications.component.ts @@ -4,6 +4,7 @@ import { PostsService } from 'app/posts.services'; import { Notification, NotificationType } from 'api-types'; import { NotificationAction } from 'api-types/models/NotificationAction'; import { MatChipListboxChange } from '@angular/material/chips'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-notifications', @@ -43,11 +44,9 @@ export class NotificationsComponent implements OnInit { if (this.postsService.initialized) { this.getNotifications(); } else { - this.postsService.service_initialized.subscribe(init => { - if (init) { - this.getNotifications(); - } - }); + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.getNotifications()); } } diff --git a/src/app/components/recent-videos/recent-videos.component.ts b/src/app/components/recent-videos/recent-videos.component.ts index 69d02f6..0dd3ed9 100644 --- a/src/app/components/recent-videos/recent-videos.component.ts +++ b/src/app/components/recent-videos/recent-videos.component.ts @@ -4,7 +4,7 @@ import { Router } from '@angular/router'; import { DatabaseFile, FileType, FileTypeFilter, Sort } from '../../../api-types'; import { MatPaginator } from '@angular/material/paginator'; import { Subject } from 'rxjs'; -import { distinctUntilChanged } from 'rxjs/operators'; +import { distinctUntilChanged, filter, take } from 'rxjs/operators'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { MatChipListboxChange } from '@angular/material/chips'; import { MatSelectionListChange } from '@angular/material/list'; @@ -116,13 +116,12 @@ export class RecentVideosComponent implements OnInit { this.getAllFiles(); this.getAllPlaylists(); } else { - const initSub = this.postsService.service_initialized.subscribe(init => { - if (init) { + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => { this.getAllFiles(); this.getAllPlaylists(); - initSub.unsubscribe(); - } - }); + }); } this.postsService.files_changed.subscribe(changed => { diff --git a/src/app/components/tasks/tasks.component.ts b/src/app/components/tasks/tasks.component.ts index 4128dc9..4237de7 100644 --- a/src/app/components/tasks/tasks.component.ts +++ b/src/app/components/tasks/tasks.component.ts @@ -10,6 +10,7 @@ import { PostsService } from 'app/posts.services'; import { Task, TaskType } from 'api-types'; import { TaskSettingsComponent } from '../task-settings/task-settings.component'; import { Clipboard } from '@angular/cdk/clipboard'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-tasks', @@ -47,11 +48,9 @@ export class TasksComponent implements OnInit { if (this.postsService.initialized) { this.getTasksRecurring(); } else { - this.postsService.service_initialized.subscribe(init => { - if (init) { - this.getTasksRecurring(); - } - }); + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.getTasksRecurring()); } } diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts index a52dfc9..7920d6e 100644 --- a/src/app/main/main.component.ts +++ b/src/app/main/main.component.ts @@ -11,6 +11,7 @@ import { Platform } from '@angular/cdk/platform'; import { ArgModifierDialogComponent } from 'app/dialogs/arg-modifier-dialog/arg-modifier-dialog.component'; import { RecentVideosComponent } from 'app/components/recent-videos/recent-videos.component'; import { DatabaseFile, Download, FileType, Playlist } from 'api-types'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-root', @@ -250,11 +251,9 @@ export class MainComponent implements OnInit { if (this.postsService.initialized) { this.configLoad(); } else { - this.postsService.service_initialized.subscribe(init => { - if (init) { - this.configLoad(); - } - }); + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.configLoad()); } this.postsService.config_reloaded.subscribe(changed => { diff --git a/src/app/player/player.component.ts b/src/app/player/player.component.ts index 81aa512..76d4176 100644 --- a/src/app/player/player.component.ts +++ b/src/app/player/player.component.ts @@ -9,6 +9,7 @@ import { DatabaseFile, FileType, Playlist } from '../../api-types'; import { TwitchChatComponent } from 'app/components/twitch-chat/twitch-chat.component'; import { VideoInfoDialogComponent } from 'app/dialogs/video-info-dialog/video-info-dialog.component'; import { saveAs } from 'file-saver'; +import { filter, take } from 'rxjs/operators'; export interface IMedia { title: string; @@ -84,11 +85,9 @@ export class PlayerComponent implements OnInit, AfterViewInit, OnDestroy { if (this.postsService.initialized) { this.processConfig(); } else { - this.postsService.service_initialized.subscribe(init => { // loads settings - if (init) { - this.processConfig(); - } - }); + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => this.processConfig()); } } @@ -154,6 +153,9 @@ export class PlayerComponent implements OnInit, AfterViewInit, OnDestroy { this.uids = [this.db_file['uid']]; this.type = this.db_file['isAudio'] ? 'audio' as FileType : 'video' as FileType; this.parseFileNames(); + }, err => { + console.error(err); + this.postsService.openSnackBar($localize`Failed to get file information from the server.`, 'Dismiss'); }); } @@ -161,7 +163,7 @@ export class PlayerComponent implements OnInit, AfterViewInit, OnDestroy { this.postsService.getSubscription(this.sub_id).subscribe(res => { const subscription = res['subscription']; this.subscription = subscription; - this.type === this.subscription.type; + this.type = this.subscription.type; this.uids = this.subscription.videos.map(video => video['uid']); this.parseFileNames(); }, () => { diff --git a/src/app/posts.services.ts b/src/app/posts.services.ts index b976865..ec21331 100644 --- a/src/app/posts.services.ts +++ b/src/app/posts.services.ts @@ -823,8 +823,11 @@ export class PostsService { } setInitialized() { - this.service_initialized.next(true); + if (this.initialized) { + return; + } this.initialized = true; + this.service_initialized.next(true); this.config_reloaded.next(true); } diff --git a/src/app/settings/settings.component.ts b/src/app/settings/settings.component.ts index 2a37d2f..fd9ab0c 100644 --- a/src/app/settings/settings.component.ts +++ b/src/app/settings/settings.component.ts @@ -14,6 +14,7 @@ import { EditCategoryDialogComponent } from 'app/dialogs/edit-category-dialog/ed import { ActivatedRoute, Router } from '@angular/router'; import { Category, DBInfoResponse } from 'api-types'; import { GenerateRssUrlComponent } from 'app/dialogs/generate-rss-url/generate-rss-url.component'; +import { filter, take } from 'rxjs/operators'; type CookiesTestResponse = { success: boolean; @@ -75,12 +76,12 @@ export class SettingsComponent implements OnInit { this.getConfig(); this.getDBInfo(); } else { - this.postsService.service_initialized.subscribe(init => { - if (init) { + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => { this.getConfig(); this.getDBInfo(); - } - }); + }); } this.generated_bookmarklet_code = this.sanitizer.bypassSecurityTrustUrl(this.generateBookmarkletCode()); diff --git a/src/app/subscription/subscription/subscription.component.ts b/src/app/subscription/subscription/subscription.component.ts index 3d53857..303e70a 100644 --- a/src/app/subscription/subscription/subscription.component.ts +++ b/src/app/subscription/subscription/subscription.component.ts @@ -5,6 +5,7 @@ import { MatDialog } from '@angular/material/dialog'; import { EditSubscriptionDialogComponent } from 'app/dialogs/edit-subscription-dialog/edit-subscription-dialog.component'; import { Subscription } from 'api-types'; import { saveAs } from 'file-saver'; +import { filter, take } from 'rxjs/operators'; @Component({ selector: 'app-subscription', @@ -31,13 +32,13 @@ export class SubscriptionComponent implements OnInit, OnDestroy { if (this.sub_interval) { clearInterval(this.sub_interval); } - this.postsService.service_initialized.subscribe(init => { - if (init) { + this.postsService.service_initialized + .pipe(filter(Boolean), take(1)) + .subscribe(() => { this.getConfig(); this.getSubscription(); this.sub_interval = setInterval(() => this.getSubscription(true), 1000); - } - }); + }); }); }