SaveStatus.tsx 2.28 KB
Newer Older
dechen lin's avatar
dechen lin committed
1
2
3
4
5
6
import React, {
  useState,
  useEffect,
  useImperativeHandle,
  forwardRef,
} from "react";
dechen lin's avatar
dechen lin committed
7
import cls from "classnames";
dechen lin's avatar
dechen lin committed
8
9
10
11
12
13
14

interface SaveStatusProps {
  className?: string;
}

export interface SaveStatusRef {
  triggerSave: () => void;
dechen lin's avatar
dechen lin committed
15
  reset: () => void; // 新增的重置方法
dechen lin's avatar
dechen lin committed
16
17
18
19
20
21
}

const SaveStatus = forwardRef<SaveStatusRef, SaveStatusProps>(
  ({ className }, ref) => {
    const [lastSaveTime, setLastSaveTime] = useState<Date | null>(null);
    const [showSaved, setShowSaved] = useState(false);
dechen lin's avatar
dechen lin committed
22
    const [timeSinceLastSave, setTimeSinceLastSave] = useState(0);
dechen lin's avatar
dechen lin committed
23
24
25
26
27
28

    useImperativeHandle(ref, () => ({
      triggerSave: () => {
        setLastSaveTime(new Date());
        setShowSaved(true);
      },
dechen lin's avatar
dechen lin committed
29
30
31
32
      reset: () => {
        // 新增的重置方法
        setLastSaveTime(null);
        setShowSaved(false);
dechen lin's avatar
dechen lin committed
33
        setTimeSinceLastSave(0);
dechen lin's avatar
dechen lin committed
34
      },
dechen lin's avatar
dechen lin committed
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    }));

    useEffect(() => {
      if (showSaved) {
        const timer = setTimeout(() => {
          setShowSaved(false);
        }, 10000);
        return () => clearTimeout(timer);
      }
    }, [showSaved]);

    useEffect(() => {
      const updateTimeSinceLastSave = () => {
        if (lastSaveTime) {
          const now = new Date();
          const diffInMinutes = Math.floor(
            (now.getTime() - lastSaveTime.getTime()) / 60000
          );
          if (diffInMinutes > 0) {
dechen lin's avatar
dechen lin committed
54
            setTimeSinceLastSave(diffInMinutes);
dechen lin's avatar
dechen lin committed
55
56
57
58
59
60
61
62
63
64
          }
        }
      };

      const timer = setInterval(updateTimeSinceLastSave, 60000);
      updateTimeSinceLastSave(); // 立即更新一次
      return () => clearInterval(timer);
    }, [lastSaveTime]);

    return (
dechen lin's avatar
dechen lin committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
      <div className={cls("flex items-center", className)}>
        {showSaved && (
          <span className="text-[#121316]/[0.6] text-[13px] leading-[24px]">
            已保存
          </span>
        )}
        {timeSinceLastSave > 0 && !showSaved && lastSaveTime && (
          <span className="text-[#121316]/[0.6] text-[13px] leading-[24px]">
            最近修改:{timeSinceLastSave} 分钟前
          </span>
        )}
        {(showSaved ||
          (timeSinceLastSave > 0 && !showSaved && lastSaveTime)) && (
          <span className="w-[1px] h-[0.75rem] bg-[#D7D8DD] ml-[1rem] block"></span>
dechen lin's avatar
dechen lin committed
79
80
81
82
83
84
85
        )}
      </div>
    );
  }
);

export default SaveStatus;