feat(onboarding): add progress bar to feed subscription step

Introduces a progress bar to visually indicate the completion status of feed subscriptions during onboarding. Progress updates as each feed is processed, and the bar is shown after a short delay for improved user feedback.
This commit is contained in:
songkeys 2025-11-02 17:26:19 +08:00
parent 9688b20a00
commit c356ddfc94
1 changed files with 35 additions and 2 deletions

View File

@ -1,8 +1,9 @@
import { Progress } from "@follow/components/ui/progress/index.js"
import { FeedViewType } from "@follow/constants"
import { subscriptionSyncService } from "@follow/store/subscription/store"
import Spline from "@splinetool/react-spline"
import { useAtomValue, useSetAtom } from "jotai"
import { useEffect, useMemo } from "react"
import { useEffect, useMemo, useState } from "react"
import { feedSelectionsAtom, stepAtom } from "./store"
@ -17,11 +18,33 @@ export function PreFinish() {
() => feedSelections.filter((feed) => feed.selected),
[feedSelections],
)
const [progress, setProgress] = useState(selectedFeeds.length === 0 ? 100 : 0)
const [showProgress, setShowProgress] = useState(false)
useEffect(() => {
setProgress(selectedFeeds.length === 0 ? 100 : 0)
setShowProgress(false)
const timer = window.setTimeout(() => setShowProgress(true), WAIT_DURATION_MS)
return () => {
window.clearTimeout(timer)
}
}, [selectedFeeds])
useEffect(() => {
let disposed = false
const subscribeSelectedFeeds = async () => {
if (selectedFeeds.length === 0) {
if (!disposed) {
setProgress(100)
}
return
}
let completed = 0
for (const feed of selectedFeeds) {
if (disposed) break
const { url, id, title } = feed
@ -41,6 +64,11 @@ export function PreFinish() {
if (!disposed) {
console.error("Failed to subscribe feed during onboarding", { feedId: id, error })
}
} finally {
completed += 1
if (!disposed) {
setProgress(Math.round((completed / selectedFeeds.length) * 100))
}
}
}
}
@ -65,7 +93,12 @@ export function PreFinish() {
}, [selectedFeeds, setStep])
return (
<div className="h-[100vh] w-screen">
<div className="relative h-[100vh] w-screen">
{showProgress ? (
<div className="pointer-events-none absolute bottom-12 left-1/2 flex w-full -translate-x-1/2 justify-center px-6">
<Progress value={progress} max={100} aria-label="Subscription progress" />
</div>
) : null}
<Spline scene="https://prod.spline.design/07pKu5Ohpb-J2VPw/scene.splinecode" />
</div>
)