116 lines
3.0 KiB
TypeScript
116 lines
3.0 KiB
TypeScript
export interface ProgressValue {
|
|
current: number
|
|
total: number
|
|
secondary?: ProgressValue | null
|
|
}
|
|
|
|
export interface ProgressSnapshot {
|
|
phase: string
|
|
progress?: ProgressValue | null
|
|
parallel?: {
|
|
phase: string
|
|
current: number
|
|
total: number
|
|
} | null
|
|
}
|
|
|
|
export interface ProgressTextSnapshot extends ProgressSnapshot {
|
|
status: string
|
|
details?: { type: string; step?: string } | null
|
|
summary: {
|
|
files_completed: number
|
|
files_total?: number | null
|
|
bytes_downloaded: number
|
|
bytes_total?: number | null
|
|
}
|
|
}
|
|
|
|
export type InstallProgressTextSource =
|
|
| { type: 'required_files' | 'phase' }
|
|
| { type: 'bytes' | 'items'; current: number; total: number }
|
|
|
|
export function effectiveInstallProgress(
|
|
snapshot: ProgressSnapshot,
|
|
): ProgressValue | null | undefined {
|
|
if (snapshot.phase === 'downloading_content' && snapshot.progress?.secondary) {
|
|
return snapshot.progress.secondary
|
|
}
|
|
|
|
return snapshot.progress
|
|
}
|
|
|
|
export function effectiveParallelProgress(
|
|
snapshot: ProgressSnapshot,
|
|
): ProgressValue | null | undefined {
|
|
if (!snapshot.parallel) return null
|
|
return {
|
|
current: snapshot.parallel.current,
|
|
total: snapshot.parallel.total,
|
|
}
|
|
}
|
|
|
|
export function hasDeterminateInstallProgress(
|
|
progress: ProgressValue | null | undefined,
|
|
): progress is ProgressValue {
|
|
return (
|
|
progress != null &&
|
|
Number.isFinite(progress.current) &&
|
|
Number.isFinite(progress.total) &&
|
|
progress.current >= 0 &&
|
|
progress.total > 0
|
|
)
|
|
}
|
|
|
|
export function installProgressFraction(snapshot: ProgressSnapshot): number | null {
|
|
const progress = effectiveInstallProgress(snapshot)
|
|
if (!hasDeterminateInstallProgress(progress)) return null
|
|
|
|
return Math.max(0, Math.min(1, progress.current / progress.total))
|
|
}
|
|
|
|
export function installProgressTextSource(
|
|
snapshot: ProgressTextSnapshot,
|
|
): InstallProgressTextSource {
|
|
if (snapshot.status === 'waiting_for_user') return { type: 'required_files' }
|
|
|
|
const isContentDownload = snapshot.phase === 'downloading_content'
|
|
const isByteDownload =
|
|
snapshot.phase === 'downloading_pack_file' ||
|
|
snapshot.phase === 'downloading_minecraft' ||
|
|
(snapshot.phase === 'preparing_java' &&
|
|
snapshot.details?.type === 'java' &&
|
|
snapshot.details.step === 'downloading')
|
|
const progress = effectiveInstallProgress(snapshot)
|
|
if (hasDeterminateInstallProgress(progress)) {
|
|
if (isContentDownload) {
|
|
return {
|
|
type: snapshot.progress?.secondary ? 'bytes' : 'items',
|
|
current: progress.current,
|
|
total: progress.total,
|
|
}
|
|
}
|
|
if (isByteDownload) {
|
|
return { type: 'bytes', current: progress.current, total: progress.total }
|
|
}
|
|
}
|
|
|
|
if (snapshot.progress != null) return { type: 'phase' }
|
|
|
|
if ((isContentDownload || isByteDownload) && snapshot.summary.bytes_total) {
|
|
return {
|
|
type: 'bytes',
|
|
current: snapshot.summary.bytes_downloaded,
|
|
total: snapshot.summary.bytes_total,
|
|
}
|
|
}
|
|
if (isContentDownload && snapshot.summary.files_total) {
|
|
return {
|
|
type: 'items',
|
|
current: snapshot.summary.files_completed,
|
|
total: snapshot.summary.files_total,
|
|
}
|
|
}
|
|
|
|
return { type: 'phase' }
|
|
}
|