fix scroll position

This commit is contained in:
2026-03-11 18:33:41 +01:00
parent 196e8c80d8
commit 6280d04ee7
7 changed files with 28 additions and 34 deletions

View File

@@ -11,13 +11,20 @@ export class SongDataService {
private dbService = inject(DbService);
private collection = 'songs';
public list$: Observable<Song[]> = this.dbService.col$<Song>(this.collection).pipe(
private loadedList$: Observable<Song[]> = this.dbService.col$<Song>(this.collection).pipe(
shareReplay({
bufferSize: 1,
refCount: false, // keep the listener alive after first subscription to avoid reloading on navigation
})
);
public list$: Observable<Song[]> = this.loadedList$.pipe(
startWith([] as Song[]), // immediate empty emit keeps UI responsive while first snapshot arrives
shareReplay({
bufferSize: 1,
refCount: false, // keep the listener alive after first subscription to avoid reloading on navigation
})
);
public listLoaded$ = (): Observable<Song[]> => this.loadedList$;
public read$ = (songId: string): Observable<Song | null> => this.dbService.doc$(this.collection + '/' + songId);
public update$ = async (songId: string, data: Partial<Song>): Promise<void> => await this.dbService.doc(this.collection + '/' + songId).update(data);

View File

@@ -12,6 +12,6 @@ export class SongListResolver {
private songService = inject(SongService);
public resolve(): Observable<Song[]> {
return this.songService.list$().pipe(take(1));
return this.songService.listLoaded$().pipe(take(1));
}
}

View File

@@ -26,6 +26,7 @@ export class SongService {
public static LEGAL_TYPE: SongLegalType[] = ['open', 'allowed'];
public list$ = (): Observable<Song[]> => this.songDataService.list$; //.pipe(tap(_ => (this.list = _)));
public listLoaded$ = (): Observable<Song[]> => this.songDataService.listLoaded$();
public read$ = (songId: string): Observable<Song | null> => this.songDataService.read$(songId);
public read = (songId: string): Promise<Song | null> => firstValueFrom(this.read$(songId));

View File

@@ -1,13 +1,11 @@
import {ChangeDetectionStrategy, Component, OnDestroy, OnInit, inject} from '@angular/core';
import {SongService} from '../services/song.service';
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {Song} from '../services/song';
import {map} from 'rxjs/operators';
import {combineLatest, Observable} from 'rxjs';
import {fade} from '../../../animations';
import {RouterLink} from '@angular/router';
import {ActivatedRoute, RouterLink} from '@angular/router';
import {filterSong} from '../../../services/filter.helper';
import {FilterValues} from './filter/filter-values';
import {ScrollService} from '../../../services/scroll.service';
import {faBalanceScaleRight, faCheck, faPencilRuler} from '@fortawesome/free-solid-svg-icons';
import {TextRenderingService} from '../services/text-rendering.service';
import {FilterStoreService} from '../../../services/filter-store.service';
@@ -30,16 +28,15 @@ interface SongListItem extends Song {
animations: [fade],
imports: [ListHeaderComponent, FilterComponent, CardComponent, RouterLink, RoleDirective, FaIconComponent, AsyncPipe],
})
export class SongListComponent implements OnInit, OnDestroy {
private songService = inject(SongService);
private scrollService = inject(ScrollService);
export class SongListComponent {
private route = inject(ActivatedRoute);
private textRenderingService = inject(TextRenderingService);
private filterStore = inject(FilterStoreService);
public anyFilterActive = false;
public songs$: Observable<SongListItem[]> = combineLatest([
this.filterStore.songFilter$,
this.songService.list$().pipe(map(songs => [...songs].sort((a, b) => a.number - b.number))),
this.route.data.pipe(map(data => (data['songs'] as Song[]).slice().sort((a, b) => a.number - b.number))),
]).pipe(
map(([filter, songs]) => {
this.anyFilterActive = this.checkIfFilterActive(filter);
@@ -56,15 +53,6 @@ export class SongListComponent implements OnInit, OnDestroy {
public faDraft = faPencilRuler;
public faFinal = faCheck;
public ngOnInit(): void {
setTimeout(() => this.scrollService.restoreScrollPositionFor('songlist'), 100);
setTimeout(() => this.scrollService.restoreScrollPositionFor('songlist'), 300);
}
public ngOnDestroy(): void {
this.scrollService.storeScrollPositionFor('songlist');
}
public trackBy = (index: number, show: SongListItem) => show.id;
private filter(song: Song, filter: FilterValues): boolean {

View File

@@ -5,12 +5,16 @@ import {SongListComponent} from './song-list/song-list.component';
import {EditComponent} from './song/edit/edit.component';
import {NewComponent} from './song/new/new.component';
import {EditSongGuard} from './song/edit/edit-song.guard';
import {SongListResolver} from './services/song-list.resolver';
const routes: Routes = [
{
path: '',
component: SongListComponent,
pathMatch: 'full',
resolve: {
songs: SongListResolver,
},
},
{
path: 'new',