Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export { objectToFormData } from './formData'
export { formDataToObject } from './formObject'
export { default as createHeadManager } from './head'
export { shouldIntercept, shouldNavigate } from './navigationEvents'
export { hide as hideProgress, reveal as revealProgress, default as setupProgress } from './progress'
export { hide as hideProgress, progress, reveal as revealProgress, default as setupProgress } from './progress'
export { resetFormFields } from './resetFormFields'
export * from './types'
export { hrefToUrl, isUrlMethodPair, mergeDataIntoQueryString, urlWithoutHash } from './url'
Expand Down
78 changes: 56 additions & 22 deletions packages/core/src/progress.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,90 @@
import ProgressComponent from './progress-component'
import { GlobalEvent } from './types'

let hideCount = 0
class Progress {
public hideCount = 0

export const reveal = (force = false) => {
hideCount = Math.max(0, hideCount - 1)
public start(): void {
ProgressComponent.start()
}

public reveal(force: boolean = false): void {
this.hideCount = Math.max(0, this.hideCount - 1)

if (force || hideCount === 0) {
ProgressComponent.show()
if (force || this.hideCount === 0) {
ProgressComponent.show()
}
}
}

export const hide = () => {
hideCount++
public hide(): void {
this.hideCount++

ProgressComponent.hide()
}

public set(status: number): void {
ProgressComponent.set(Math.max(0, Math.min(1, status)))
}

public finish(): void {
ProgressComponent.done()
}

public reset(): void {
ProgressComponent.set(0)
}

ProgressComponent.hide()
public remove(): void {
ProgressComponent.done()
ProgressComponent.remove()
}

public isStarted(): boolean {
return ProgressComponent.isStarted()
}

public getStatus(): number | null {
return ProgressComponent.status
}
}

export const progress = new Progress()
export const reveal = progress.reveal
export const hide = progress.hide

function addEventListeners(delay: number): void {
document.addEventListener('inertia:start', (e) => start(e, delay))
document.addEventListener('inertia:progress', progress)
document.addEventListener('inertia:start', (e) => handleStartEvent(e, delay))
document.addEventListener('inertia:progress', handleProgressEvent)
}

function start(event: GlobalEvent<'start'>, delay: number): void {
function handleStartEvent(event: GlobalEvent<'start'>, delay: number): void {
if (!event.detail.visit.showProgress) {
hide()
progress.hide()
}

const timeout = setTimeout(() => ProgressComponent.start(), delay)
const timeout = setTimeout(() => progress.start(), delay)
document.addEventListener('inertia:finish', (e) => finish(e, timeout), { once: true })
}

function progress(event: GlobalEvent<'progress'>): void {
if (ProgressComponent.isStarted() && event.detail.progress?.percentage) {
ProgressComponent.set(Math.max(ProgressComponent.status!, (event.detail.progress.percentage / 100) * 0.9))
function handleProgressEvent(event: GlobalEvent<'progress'>): void {
if (progress.isStarted() && event.detail.progress?.percentage) {
progress.set(Math.max(progress.getStatus()!, (event.detail.progress.percentage / 100) * 0.9))
}
}

function finish(event: GlobalEvent<'finish'>, timeout: NodeJS.Timeout): void {
clearTimeout(timeout!)

if (!ProgressComponent.isStarted()) {
if (!progress.isStarted()) {
return
}

if (event.detail.visit.completed) {
ProgressComponent.done()
progress.finish()
} else if (event.detail.visit.interrupted) {
ProgressComponent.set(0)
progress.reset()
} else if (event.detail.visit.cancelled) {
ProgressComponent.done()
ProgressComponent.remove()
progress.remove()
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/router.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hideProgress, revealProgress } from '.'
import { progress } from '.'
import { eventHandler } from './eventHandler'
import { fireBeforeEvent } from './events'
import { history } from './history'
Expand Down Expand Up @@ -192,10 +192,10 @@ export class Router {
const prefetched = prefetchedRequests.get(requestParams)

if (prefetched) {
revealProgress(prefetched.inFlight)
progress.reveal(prefetched.inFlight)
prefetchedRequests.use(prefetched, requestParams)
} else {
revealProgress(true)
progress.reveal(true)
requestStream.send(Request.create(requestParams, currentPage.get()))
}
}
Expand Down Expand Up @@ -259,7 +259,7 @@ export class Router {
return
}

hideProgress()
progress.hide()

this.asyncRequestStream.interruptInFlight()

Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { router as Router } from '@inertiajs/core'
import { progress as Progress, router as Router } from '@inertiajs/core'

export const progress = Progress
export const router = Router
export { default as createInertiaApp } from './createInertiaApp'
export { default as Deferred } from './Deferred'
Expand Down
109 changes: 109 additions & 0 deletions packages/react/test-app/Pages/ProgressComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { progress } from '@inertiajs/react'
import { useState } from 'react'

declare global {
interface Window {
progressTests: any[]
}
}

window.progressTests = []

export default () => {
const [logs, setLogs] = useState<string[]>([])

const log = (...args: any[]) => {
const message = args.join(' ')
window.progressTests.push(...args)
setLogs((prevLogs) => [...prevLogs, message])
}

const testStart = () => {
progress.start()
log('started')
}

const testSet25 = () => {
progress.set(0.25)
log('set 25%')
}

const testSet50 = () => {
progress.set(0.5)
log('set 50%')
}

const testSet75 = () => {
progress.set(0.75)
log('set 75%')
}

const testFinish = () => {
progress.finish()
log('finished')
}

const testReset = () => {
progress.reset()
log('reset')
}

const testRemove = () => {
progress.remove()
log('removed')
}

const testHide = () => {
progress.hide()
log('hidden')
}

const testReveal = () => {
progress.reveal()
log('revealed')
}

const testIsStarted = () => {
log('isStarted:', progress.isStarted())
}

const testGetStatus = () => {
log('getStatus:', progress.getStatus())
}

const clearLogs = () => {
window.progressTests = []
setLogs([])
}

return (
<div>
<h1>Progress API Test</h1>

<div>
<button onClick={testStart}>Start</button>
<button onClick={testSet25}>Set 25%</button>
<button onClick={testSet50}>Set 50%</button>
<button onClick={testSet75}>Set 75%</button>
<button onClick={testFinish}>Finish</button>
</div>

<div>
<button onClick={testReset}>Reset</button>
<button onClick={testRemove}>Remove</button>
<button onClick={testHide}>Hide</button>
<button onClick={testReveal}>Reveal</button>
</div>

<div>
<button onClick={testIsStarted}>Is Started</button>
<button onClick={testGetStatus}>Get Status</button>
<button onClick={clearLogs}>Clear</button>
</div>

<div>
Logs: <span id="logs">{logs.join(', ')}</span>
</div>
</div>
)
}
2 changes: 1 addition & 1 deletion packages/svelte/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { router } from '@inertiajs/core'
export { progress, router } from '@inertiajs/core'
export { default as Deferred } from './components/Deferred.svelte'
export { default as Form } from './components/Form.svelte'
export { default as Link } from './components/Link.svelte'
Expand Down
108 changes: 108 additions & 0 deletions packages/svelte/test-app/Pages/ProgressComponent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<script context="module" lang="ts">
declare global {
interface Window {
progressTests: any[]
}
}
</script>

<script lang="ts">
import { progress } from '@inertiajs/svelte'

window.progressTests = []

let logs: string[] = []

const log = (...args: any[]) => {
const message = args.join(' ')
window.progressTests.push(...args)
logs = [...logs, message]
}

const testStart = () => {
progress.start()
log('started')
}

const testSet25 = () => {
progress.set(0.25)
log('set 25%')
}

const testSet50 = () => {
progress.set(0.5)
log('set 50%')
}

const testSet75 = () => {
progress.set(0.75)
log('set 75%')
}

const testFinish = () => {
progress.finish()
log('finished')
}

const testReset = () => {
progress.reset()
log('reset')
}

const testRemove = () => {
progress.remove()
log('removed')
}

const testHide = () => {
progress.hide()
log('hidden')
}

const testReveal = () => {
progress.reveal()
log('revealed')
}

const testIsStarted = () => {
log('isStarted:', progress.isStarted())
}

const testGetStatus = () => {
log('getStatus:', progress.getStatus())
}

const clearLogs = () => {
window.progressTests = []
logs = []
}
</script>

<div>
<h1>Progress API Test</h1>

<div>
<button on:click={testStart}>Start</button>
<button on:click={testSet25}>Set 25%</button>
<button on:click={testSet50}>Set 50%</button>
<button on:click={testSet75}>Set 75%</button>
<button on:click={testFinish}>Finish</button>
</div>

<div>
<button on:click={testReset}>Reset</button>
<button on:click={testRemove}>Remove</button>
<button on:click={testHide}>Hide</button>
<button on:click={testReveal}>Reveal</button>
</div>

<div>
<button on:click={testIsStarted}>Is Started</button>
<button on:click={testGetStatus}>Get Status</button>
<button on:click={clearLogs}>Clear</button>
</div>

<div>
Logs: <span id="logs">{logs.join(', ')}</span>
</div>
</div>
2 changes: 1 addition & 1 deletion packages/vue3/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { router } from '@inertiajs/core'
export { progress, router } from '@inertiajs/core'
export { usePage } from './app'
export { default as createInertiaApp } from './createInertiaApp'
export { default as Deferred } from './deferred'
Expand Down
Loading