'多语言'
This commit is contained in:
56
app/[locale]/course/useVideoProgress.ts
Normal file
56
app/[locale]/course/useVideoProgress.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
const STORAGE_KEY = "digital-course-video-completed";
|
||||
|
||||
function loadCompleted(): Set<string> {
|
||||
if (typeof window === "undefined") return new Set();
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) return new Set();
|
||||
const arr = JSON.parse(raw) as string[];
|
||||
return new Set(Array.isArray(arr) ? arr : []);
|
||||
} catch {
|
||||
return new Set();
|
||||
}
|
||||
}
|
||||
|
||||
function saveCompleted(ids: Set<string>) {
|
||||
if (typeof window === "undefined") return;
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify([...ids]));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export function useVideoProgress() {
|
||||
const [completed, setCompleted] = useState<Set<string>>(() => new Set());
|
||||
|
||||
useEffect(() => {
|
||||
setCompleted(loadCompleted());
|
||||
}, []);
|
||||
|
||||
const markCompleted = useCallback((lessonId: string) => {
|
||||
setCompleted((prev) => {
|
||||
const next = new Set(prev);
|
||||
next.add(lessonId);
|
||||
saveCompleted(next);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const isCompleted = useCallback(
|
||||
(lessonId: string) => completed.has(lessonId),
|
||||
[completed]
|
||||
);
|
||||
|
||||
const isPartCompleted = useCallback(
|
||||
(lessonIds: string[]) =>
|
||||
lessonIds.length > 0 && lessonIds.every((id) => completed.has(id)),
|
||||
[completed]
|
||||
);
|
||||
|
||||
return { completed, markCompleted, isCompleted, isPartCompleted };
|
||||
}
|
||||
Reference in New Issue
Block a user