import {
ChangeDetectionStrategy,
Component,
inject,
signal,
} from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { Router } from '@angular/router'
import {
DialogService,
formatProgress,
getErrorMessage,
i18nPipe,
InitializingComponent,
LoadingService,
} from '@start9labs/shared'
import { T } from '@start9labs/start-sdk'
import { TuiButton } from '@taiga-ui/core'
import {
catchError,
filter,
from,
map,
startWith,
switchMap,
tap,
timer,
} from 'rxjs'
import { ApiService } from '../services/api.service'
import { StateService } from '../services/state.service'
@Component({
template: `
@if (error(); as err) {
{{ 'Error initializing server' | i18n }}
{{ err }}
} @else {
}
`,
styles: `
:host {
max-width: unset;
align-items: stretch;
}
section {
border-radius: 0.25rem;
padding: 1rem;
margin: 1.5rem;
text-align: center;
background: #e0e0e0;
color: #333;
--tui-background-neutral-1: rgba(0, 0, 0, 0.1);
}
`,
imports: [InitializingComponent, TuiButton, i18nPipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class LoadingPage {
private readonly api = inject(ApiService)
private readonly loader = inject(LoadingService)
private readonly dialog = inject(DialogService)
private readonly router = inject(Router)
readonly type = inject(StateService).setupType
readonly progress = toSignal(
from(this.getStatus()).pipe(
filter(Boolean),
switchMap(({ guid, progress }) =>
this.api.openWebsocket$(guid).pipe(
startWith(progress),
tap(({ overall }) => {
if (overall === true) {
this.getStatus()
}
}),
),
),
map(formatProgress),
catchError((_, caught$) => timer(500).pipe(switchMap(() => caught$))),
),
{ initialValue: { total: 0, message: '' } },
)
error = signal('')
private async getStatus(): Promise<{
status: 'running'
guid: string
progress: T.FullProgress
} | null> {
try {
const res = await this.api.getStatus()
if (res.status === 'running') {
return res
} else if (res.status === 'complete') {
this.router.navigate(['/success'])
} else {
// incomplete or needs-install - shouldn't happen on loading page
this.router.navigate(['/language'])
}
} catch (e: any) {
this.error.set(getErrorMessage(e))
}
return null
}
async restart(): Promise {
const loader = this.loader.open(undefined).subscribe()
try {
await this.api.restart()
this.dialog
.openAlert('Wait 1-2 minutes and refresh the page', {
label: 'Server is restarting',
})
.subscribe()
} catch (e) {
console.error(e)
} finally {
loader.unsubscribe()
}
}
}