From 994c446de8bf91b03c3f89860507c21d74d81f86 Mon Sep 17 00:00:00 2001 From: Jan Kaiser Date: Mon, 14 Aug 2023 19:31:04 +0200 Subject: [PATCH] fix: load readme relative to path, link to readme --- .../src/app/app-routing.module.ts | 6 +++- .../file-explorer-about.component.html | 4 +-- .../file-explorer-about.component.ts | 2 ++ .../file-explorer.component.html | 4 ++- .../file-explorer.component.spec.ts | 3 ++ .../file-explorer/file-explorer.component.ts | 25 +++++++++++++---- .../repository/services/repository.service.ts | 28 +++++++++++++------ .../state/repository/repository.effects.ts | 3 +- 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/angular-ngrx-scss/src/app/app-routing.module.ts b/angular-ngrx-scss/src/app/app-routing.module.ts index bd9f9a742..2573c890f 100644 --- a/angular-ngrx-scss/src/app/app-routing.module.ts +++ b/angular-ngrx-scss/src/app/app-routing.module.ts @@ -18,7 +18,11 @@ const routes: Routes = [ @NgModule({ imports: [ - RouterModule.forRoot(routes, { paramsInheritanceStrategy: 'always' }), + RouterModule.forRoot(routes, { + paramsInheritanceStrategy: 'always', + scrollPositionRestoration: 'enabled', + anchorScrolling: 'enabled', + }), ], exports: [RouterModule], }) diff --git a/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.html b/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.html index 9fe43f97e..d416bd2d6 100644 --- a/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.html +++ b/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.html @@ -20,9 +20,7 @@

About

- - - + Readme
diff --git a/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.ts b/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.ts index fddbd1bd9..46b0639d5 100644 --- a/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.ts +++ b/angular-ngrx-scss/src/app/file-viewer/components/file-explorer-about/file-explorer-about.component.ts @@ -10,4 +10,6 @@ export class FileExplorerAboutComponent { @Input() description: string | undefined; @Input() homepageUrl!: string; @Input() topics!: string[]; + @Input() owner!: string; + @Input() name!: string; } diff --git a/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.html b/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.html index 199bad9d2..24df2cfb9 100644 --- a/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.html +++ b/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.html @@ -22,10 +22,12 @@ [description]="repo.description" [homepageUrl]="repo.website" [topics]="repo.tags" + [owner]="owner" + [name]="repoName" > -
+
diff --git a/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.spec.ts b/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.spec.ts index 3e91438b7..2b97cf536 100644 --- a/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.spec.ts +++ b/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.spec.ts @@ -49,6 +49,9 @@ describe('FileExplorerComponent', () => { } }, }), + snapshot: { + fragment: '', + }, }; beforeEach(async () => { diff --git a/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.ts b/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.ts index 6bcec90c2..d1849c61e 100644 --- a/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.ts +++ b/angular-ngrx-scss/src/app/file-viewer/file-explorer/file-explorer.component.ts @@ -1,15 +1,19 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Store } from '@ngrx/store'; import { ActivatedRoute } from '@angular/router'; import { RepoContents, fetchRepository, selectedRepository } from '../../state/repository'; -import { map, takeWhile, tap } from 'rxjs'; +import { map, take, takeWhile, tap } from 'rxjs'; @Component({ selector: 'app-file-explorer', templateUrl: './file-explorer.component.html', styleUrls: ['./file-explorer.component.scss'], }) -export class FileExplorerComponent implements OnDestroy { +export class FileExplorerComponent implements OnInit, OnDestroy { + @ViewChild('readme') readmeContainer: ElementRef | undefined; + + private componentActive = true; + owner = ''; repoName = ''; path = ''; @@ -29,10 +33,18 @@ export class FileExplorerComponent implements OnDestroy { return { ...repo, tree: dirItems.concat(fileItems) }; }), + tap(() => { + // make sure the readme is scrolled into view if the fragment is set + // we need to wait for the readme to be rendered before we can scroll to it + this.zone.onStable.pipe(take(1)).subscribe(() => { + if (this.route.snapshot.fragment === 'readme') { + this.readmeContainer?.nativeElement?.scrollIntoView(); + } + }); + }), ); - private componentActive = true; - constructor(private route: ActivatedRoute, private store: Store) { } + constructor(private route: ActivatedRoute, private store: Store, private zone: NgZone) { } ngOnInit() { @@ -57,7 +69,8 @@ export class FileExplorerComponent implements OnDestroy { .subscribe(); } - ngOnDestroy(): void { + ngOnDestroy() { this.componentActive = false; } + } diff --git a/angular-ngrx-scss/src/app/repository/services/repository.service.ts b/angular-ngrx-scss/src/app/repository/services/repository.service.ts index 9e495a7fa..50da8b5a8 100644 --- a/angular-ngrx-scss/src/app/repository/services/repository.service.ts +++ b/angular-ngrx-scss/src/app/repository/services/repository.service.ts @@ -1,6 +1,6 @@ import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable, map } from 'rxjs'; +import { Observable, catchError, map, of } from 'rxjs'; import { FileContentsApiResponse, IssueAPIResponse, @@ -373,21 +373,33 @@ export class RepositoryService { * Gets the contents of the repository's readme file * @param owner who the repo belongs to * @param repoName name of the repo + * @param path (optional) if provided, the path to retrieve the readme from; defaults to the root directory * @returns the readme file for the repository */ getRepositoryReadme( repoOwner: string, repoName: string, - ): Observable { + path?: string | null, + ): Observable { const owner = encodeURIComponent(repoOwner); const name = encodeURIComponent(repoName); - const url = `${environment.githubUrl}/repos/${owner}/${name}/readme`; + path = path ?? ''; + const url = `${environment.githubUrl}/repos/${owner}/${name}/readme/${path}`; - return this.http.get(url, { - headers: { - Accept: 'application/vnd.github.v3+json', - }, - }); + return this.http + .get(url, { + headers: { + Accept: 'application/vnd.github.v3+json', + }, + }) + .pipe( + catchError((err) => { + if (err.status === 404) { + return of(null); + } + throw err; + }), + ); } private extractTotalFromLinkHeader(linkHeader: string | null): number { diff --git a/angular-ngrx-scss/src/app/state/repository/repository.effects.ts b/angular-ngrx-scss/src/app/state/repository/repository.effects.ts index 0c5cb4192..55d50bac0 100644 --- a/angular-ngrx-scss/src/app/state/repository/repository.effects.ts +++ b/angular-ngrx-scss/src/app/state/repository/repository.effects.ts @@ -42,6 +42,7 @@ export class RepositoryEffects { const repoReadme$ = this.repoService.getRepositoryReadme( owner, repoName, + path, ); const repoMilestones$ = this.repoService.getRepositoryMilestones( @@ -83,7 +84,7 @@ export class RepositoryEffects { visibility: info.visibility, watchCount: info.watchers_count, website: info.homepage, - readme: readme.content || '', + readme: readme?.content || '', milestones: milestones || [], labels: labels || [], };