Refactor client @actorName matcher with new API route
This commit is contained in:
parent
08ac081b37
commit
69e076ddb0
|
@ -1,41 +0,0 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
|
||||||
import { empty } from 'rxjs'
|
|
||||||
import { catchError } from 'rxjs/operators'
|
|
||||||
import { RestExtractor } from '@app/core'
|
|
||||||
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
|
||||||
import { AccountService } from '@app/shared/shared-main/account'
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'my-actor',
|
|
||||||
template: ''
|
|
||||||
})
|
|
||||||
export class ActorsComponent implements OnInit {
|
|
||||||
constructor (
|
|
||||||
private accountService: AccountService,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private restExtractor: RestExtractor,
|
|
||||||
private router: Router
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit () {
|
|
||||||
const accountOrChannelName = this.route.snapshot.params['actorName'].replace('@', '')
|
|
||||||
|
|
||||||
this.accountService
|
|
||||||
.getAccount(accountOrChannelName)
|
|
||||||
.pipe(
|
|
||||||
catchError(res => {
|
|
||||||
if (res.status === 404 && res.message === 'Account not found') {
|
|
||||||
this.router.navigateByUrl(`/video-channels/${accountOrChannelName}`)
|
|
||||||
return empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.restExtractor.handleError(res)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.router.navigateByUrl(`/accounts/${accountOrChannelName}`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router'
|
import { RouteReuseStrategy, RouterModule, Routes, UrlMatchResult, UrlSegment } from '@angular/router'
|
||||||
import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy'
|
import { CustomReuseStrategy } from '@app/core/routing/custom-reuse-strategy'
|
||||||
import { MenuGuards } from '@app/core/routing/menu-guard.service'
|
import { MenuGuards } from '@app/core/routing/menu-guard.service'
|
||||||
import { POSSIBLE_LOCALES } from '@shared/core-utils/i18n'
|
import { POSSIBLE_LOCALES } from '@shared/core-utils/i18n'
|
||||||
import { PreloadSelectedModulesList } from './core'
|
import { PreloadSelectedModulesList } from './core'
|
||||||
import { EmptyComponent } from './empty.component'
|
import { EmptyComponent } from './empty.component'
|
||||||
import { ActorsComponent } from './+actors/actors.component'
|
import { RootComponent } from './root.component'
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -75,8 +75,20 @@ const routes: Routes = [
|
||||||
redirectTo: 'video-channels'
|
redirectTo: 'video-channels'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':actorName',
|
matcher: (url): UrlMatchResult => {
|
||||||
component: ActorsComponent
|
// Matches /@:actorName
|
||||||
|
if (url.length === 1 && url[0].path.match(/^@[\w]+$/gm)) {
|
||||||
|
return {
|
||||||
|
consumed: url,
|
||||||
|
posParams: {
|
||||||
|
actorName: new UrlSegment(url[0].path.substr(1), {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
component: RootComponent
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { Component, OnInit } from '@angular/core'
|
||||||
|
import { catchError, distinctUntilChanged, map, switchMap } from 'rxjs/operators'
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
|
import { RestExtractor } from '@app/core'
|
||||||
|
import { ActorService } from '@app/shared/shared-main/account'
|
||||||
|
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-root',
|
||||||
|
template: ''
|
||||||
|
})
|
||||||
|
export class RootComponent implements OnInit {
|
||||||
|
constructor (
|
||||||
|
private actorService: ActorService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private restExtractor: RestExtractor,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit () {
|
||||||
|
this.route.params
|
||||||
|
.pipe(
|
||||||
|
map(params => params[ 'actorName' ]),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
switchMap(actorName => this.actorService.getActor(actorName)),
|
||||||
|
catchError(err => this.restExtractor.redirectTo404IfNotFound(err, 'other', [
|
||||||
|
HttpStatusCode.BAD_REQUEST_400,
|
||||||
|
HttpStatusCode.NOT_FOUND_404
|
||||||
|
]))
|
||||||
|
)
|
||||||
|
.subscribe(actor => {
|
||||||
|
if (actor.constructor.name === 'Account') {
|
||||||
|
this.router.navigateByUrl(`/accounts/${actor.name}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor.constructor.name === 'VideoChannel') {
|
||||||
|
this.router.navigateByUrl(`/video-channels/${actor.name}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Observable, ReplaySubject } from 'rxjs'
|
||||||
|
import { catchError, map, tap } from 'rxjs/operators'
|
||||||
|
import { HttpClient } from '@angular/common/http'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { RestExtractor } from '@app/core'
|
||||||
|
import { Account as ServerAccount, VideoChannel as ServerVideoChannel } from '@shared/models'
|
||||||
|
import { environment } from '../../../../environments/environment'
|
||||||
|
import { Account } from './account.model'
|
||||||
|
import { VideoChannel } from '../video-channel/video-channel.model'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ActorService {
|
||||||
|
static BASE_ACTOR_API_URL = environment.apiUrl + '/api/v1/actors/'
|
||||||
|
|
||||||
|
actorLoaded = new ReplaySubject<Account | VideoChannel>(1)
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private authHttp: HttpClient,
|
||||||
|
private restExtractor: RestExtractor
|
||||||
|
) {}
|
||||||
|
|
||||||
|
getActor (actorName: string): Observable<Account | VideoChannel> {
|
||||||
|
return this.authHttp.get<ServerAccount | ServerVideoChannel>(ActorService.BASE_ACTOR_API_URL + actorName)
|
||||||
|
.pipe(
|
||||||
|
map(actorHash => {
|
||||||
|
const isAccount = /\/accounts\/.+/.test(actorHash.url)
|
||||||
|
const isVideoChannel = /\/video-channels\/.+/.test(actorHash.url)
|
||||||
|
|
||||||
|
if (isAccount) {
|
||||||
|
return new Account(actorHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isVideoChannel) {
|
||||||
|
return new VideoChannel(actorHash)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
tap(actor => this.actorLoaded.next(actor)),
|
||||||
|
catchError(res => this.restExtractor.handleError(res))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
export * from './account.model'
|
export * from './account.model'
|
||||||
export * from './account.service'
|
export * from './account.service'
|
||||||
export * from './actor.model'
|
export * from './actor.model'
|
||||||
|
export * from './actor.service'
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import { LoadingBarModule } from '@ngx-loading-bar/core'
|
import { LoadingBarModule } from '@ngx-loading-bar/core'
|
||||||
import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
|
import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
|
||||||
import { SharedGlobalIconModule } from '../shared-icons'
|
import { SharedGlobalIconModule } from '../shared-icons'
|
||||||
import { AccountService } from './account'
|
import { AccountService, ActorService } from './account'
|
||||||
import {
|
import {
|
||||||
AutofocusDirective,
|
AutofocusDirective,
|
||||||
BytesPipe,
|
BytesPipe,
|
||||||
|
@ -160,6 +160,7 @@ import { VideoChannelService } from './video-channel'
|
||||||
AUTH_INTERCEPTOR_PROVIDER,
|
AUTH_INTERCEPTOR_PROVIDER,
|
||||||
|
|
||||||
AccountService,
|
AccountService,
|
||||||
|
ActorService,
|
||||||
|
|
||||||
UserHistoryService,
|
UserHistoryService,
|
||||||
UserNotificationService,
|
UserNotificationService,
|
||||||
|
|
Loading…
Reference in New Issue