Skip to content

Conversation

@barbaraperic
Copy link
Collaborator

@barbaraperic barbaraperic commented Oct 16, 2025

Description

  • Refactored the upload progress logic to clarify the conceptual hierarchy between steps, stages, and the overall upload process (mainly in the use-upload-progress hook and components)
  • The goal was to make the data model, naming, and types more expressive and consistent across the codebase — improving readability, type safety, and maintainability.

Key Changes

  1. Clarified the data model
  • Step → the smallest unit of work (creating-car, announcing-cids, etc.)

  • Stage → a grouping of one or more steps

    • first-stage = creating-car, checking-readiness, uploading-car
    • second-stage = announcing-cids
    • third-stage = finalizing-transaction
  • Upload → the complete process made up of all stages

Defined explicit StepState, StageState, and UploadState types to reflect this structure.

  1. Split types into modular files
  • Moved upload-related types and util functions into a dedicated src/types/upload/ and src/utils/upload/ directory:
  1. Renamed ambiguous variables and functions
  • progressesstepStates to reflect that these hold full step state objects, not just progress values.

  • calculateCompletionStatesgetUploadOutcome for clearer intent.

  • getStageBadgeStatusgetUploadBadgeStatus since the badge reflects overall upload state, not an individual stage.

  1. Added explicit badge-status logic to reflect publishing progress more accurately:

In progress - During:

  • 'creating-car' in progress
  • 'uploading-car' in progress
  • 'checking-readiness' in progress
  • 'announcing-cids' in progress
  • 'finalizing-transaction' in progress

Published - When:

  • 'finalizing-transaction' is completed BUT 'announcing-cids' is not yet completed

Pinned - When:

  • Both 'finalizing-transaction' AND 'announcing-cids' are completed

@barbaraperic barbaraperic self-assigned this Oct 16, 2025
@vercel
Copy link

vercel bot commented Oct 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
filecoin-pin-website Ready Ready Preview Comment Oct 23, 2025 11:24am

@github-actions
Copy link

github-actions bot commented Oct 21, 2025

Filecoin Pin Upload

IPFS Artifacts:

Onchain verification:

Payment:

  • Current Filecoin Pay balance: 1116.3342 USDFC

  • Amount deposited to Filecoin Pay by this workflow: 0.0000 USDFC

  • Data Set Storage runway: 8950 year(s) 6 month(s) 28 day(s)

    More details

Copy link
Collaborator

@SgtPooki SgtPooki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a big fan of these changes.. I love the cleanup here and consolidation of the data model.

left a few comments

onToggleExpanded={() => setActiveUploadExpanded(!activeUploadExpanded)}
pieceCid={activeUpload.pieceCid ?? ''}
progresses={activeUpload.progress}
stepStates={activeUpload.progress}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe align .progress name here to state as well?

Suggested change
stepStates={activeUpload.progress}
stepStates={activeUpload.state}

)
const uploadingStep = progresses.find((p) => p.step === 'uploading-car')
const announcingStep = progresses.find((p) => p.step === 'announcing-cids')
const { firstStageProgress, firstStageStatus, hasUploadIpniFailure } = useUploadProgress({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be an opportunity here to align StageProgress and StageStatus ? seems redundant at this point.

Comment on lines 64 to 66
getCombinedFirstStageProgress={getCombinedFirstStageProgress}
getCombinedFirstStageStatus={getCombinedFirstStageStatus}
progresses={combinedProgresses}
firstStageProgress={firstStageProgress}
firstStageStatus={firstStageStatus}
stepStates={firstStageStates}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need StageProgress, stageStatus, and stepStates now? if we have a pure function/hook that can derive firstStageProgress and firstStageStatus from stepStates then we can remove two more drilled props..

maybe not necessary now (potential future improvement.. if it helps readability/maintainence/testability), just thinking out loud.

Comment on lines 8 to 9
firstStageStatus: StepState['status']
firstStageProgress: StepState['progress']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we already had this code (and I think I added it), but I have not been a fan of explicitly declaring the "firstStage" as it's own prop.. ideally this would be codified in the "StepState" data model and handled appropriately, rather than this explicit naming of the first step.

ultimately though, the goal is simplicity since we want folks to be able to follow the code here easily.

Comment on lines 8 to 13
firstStageProgress: StepState['progress']
firstStageStatus: StepState['status']
hasUploadIpniFailure: boolean
isUploadSuccessful: boolean
isUploadFailure: boolean
uploadBadgeStatus: Status
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add jsdocs to explain what each of these mean

hasError: boolean
firstStageProgress: StepState['progress']
firstStageStatus: StepState['status']
hasUploadIpniFailure: boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hasUploadIpniFailure: boolean
hasIpniAnnounceFailure: boolean

is a little more descriptive. we don't actually "upload" to IPNI

Comment on lines 46 to 53
const firstStageProgress = getFirstStageProgress(stepStates)
const firstStageStatus = getFirstStageStatus(stepStates)
const { hasUploadIpniFailure, isUploadSuccessful, isUploadFailure } = getUploadOutcome({ stepStates, cid })
const uploadBadgeStatus = getUploadBadgeStatus({
isUploadSuccessful,
isUploadFailure,
stepStates,
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love the cleaner code inside this hook with isolated functions for getting each part defined elsewhere. This will be much easier to test.

Comment on lines 5 to 12
export const STAGE_STEPS: Record<StageId, readonly StepState['step'][]> = {
'first-stage': ['creating-car', 'checking-readiness', 'uploading-car'],
'second-stage': ['announcing-cids'],
'third-stage': ['finalizing-transaction'],
} as const

export type FirstStageGroup = Record<
'creatingCar' | 'checkingReadiness' | 'uploadingCar',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could probably use this opportunity to just use camelCase for the steps instead of kebab-case.

also, firstStageGroup isn't tied to STAGE_STEPS currently and we should lock it in to prevent breakage in the future.

check out typescript playground

const finalizingTransactionStep = stepStates.find((stepState) => stepState.step === 'finalizing-transaction')
const announcingCidsStep = stepStates.find((stepState) => stepState.step === 'announcing-cids')

if (isUploadSuccessful) return 'pinned'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like it could still show 'pinned' even if announcingCidsStep is incomplete. we should check for that first right?

@barbaraperic barbaraperic changed the title [UXIT-3480] Show “Publishing” instead of ”Pinned", when 'finalizing-transaction' is completed BUT 'announcing-cids' is not yet completed [UXIT-3480] Refactor upload progress logic and add “Publishing” badge state Oct 21, 2025
@barbaraperic barbaraperic marked this pull request as ready for review October 21, 2025 12:45
Copy link
Collaborator

@CharlyMartin CharlyMartin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super cool Barbara, great one 🎉

'in-progress': 'In progress',
completed: 'Complete',
pinned: 'Pinned',
published: 'Published',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Publishing state?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, can you clarify for me?


export interface StepState {
step: StepName
progress: number // 0–100
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we properly type progress?

type Progress =
  | 0
  | 1
  | 2
  | 3
  | 4
  | 5
  | 6
  | 7
  | 8
  | 9
  | 10
  | 11
  | 12
  | 13
  | 14
  | 15
  | 16
  | 17
  | 18
  | 19
  | 20
  | 21
  | 22
  | 23
  | 24
  | 25
  | 26
  | 27
  | 28
  | 29
  | 30
  | 31
  | 32
  | 33
  | 34
  | 35
  | 36
  | 37
  | 38
  | 39
  | 40
  | 41
  | 42
  | 43
  | 44
  | 45
  | 46
  | 47
  | 48
  | 49
  | 50
  | 51
  | 52
  | 53
  | 54
  | 55
  | 56
  | 57
  | 58
  | 59
  | 60
  | 61
  | 62
  | 63
  | 64
  | 65
  | 66
  | 67
  | 68
  | 69
  | 70
  | 71
  | 72
  | 73
  | 74
  | 75
  | 76
  | 77
  | 78
  | 79
  | 80
  | 81
  | 82
  | 83
  | 84
  | 85
  | 86
  | 87
  | 88
  | 89
  | 90
  | 91
  | 92
  | 93
  | 94
  | 95
  | 96
  | 97
  | 98
  | 99
  | 100

Or perhaps it doesn't to be as granular:

type Progress = 0 | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are so many cool utility types you can create with some infer and other typescript magic.. https://stackoverflow.com/questions/39494689/is-it-possible-to-restrict-number-to-a-certain-range

but this feels like overkill?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is yes.

…ndling

This update transitions the upload progress management from using the Progress type to the new StepState type, enhancing type safety and clarity. The changes include updates to various components and hooks to accommodate the new structure, ensuring consistent handling of upload steps and statuses throughout the application.
…anagement

This update introduces the use of custom hooks for managing step states and first stage progress, improving the clarity and maintainability of the upload process. The changes include refactoring components to utilize the new hooks, ensuring consistent handling of upload steps and statuses across the application. Additionally, the naming conventions for stage identifiers have been updated for better readability.
…cture

This update refactors the upload-related utility functions by consolidating them into more descriptive files, enhancing clarity and maintainability. The changes include updating import paths in various components and hooks to reflect the new structure, ensuring consistent usage of the updated utility functions across the application.
This update refines the UploadOutcome type by exporting it for broader use and enhances the getUploadBadgeStatus function to utilize the new type properties. The changes improve type safety and clarity in the upload progress handling, ensuring consistent status management across the application.
@barbaraperic
Copy link
Collaborator Author

Thank you both for the comments! I've made additional improvements:

  • All progress properties are renamed to stepState
  • useUploadProgress hook now only handles UploadOutcome (hasIpniAnnounceFailure, isUploadSuccessful, and isUploadFailure) and UploadBadgeStatus
  • useStepStates hook provides easy access to individual steps and stage groupings
  • useFirstStageState calculates the combined progress and status for the first stage
  • We were then able to simplify ProgressCardCombined to only take stepStates as a prop - all calculations are now done with useFirstStageState and useStepStates within the component
  • Added JSDoc comments to explain return values
  • Renamed hasUploadIpniFailurehasIpniAnnounceFailure (more descriptive)
  • Fixed badge status logic to check announcingCidsStep completion before showing 'pinned'

@SgtPooki if you agree, I'll tackle "Consider using camelCase for steps instead of kebab-case" in a separate PR 🙏

@CharlyMartin CharlyMartin self-requested a review October 23, 2025 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants