SaveStatus.tsx 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import React, {
  2. useState,
  3. useEffect,
  4. useImperativeHandle,
  5. forwardRef,
  6. } from "react";
  7. interface SaveStatusProps {
  8. className?: string;
  9. }
  10. export interface SaveStatusRef {
  11. triggerSave: () => void;
  12. }
  13. const SaveStatus = forwardRef<SaveStatusRef, SaveStatusProps>(
  14. ({ className }, ref) => {
  15. const [lastSaveTime, setLastSaveTime] = useState<Date | null>(null);
  16. const [showSaved, setShowSaved] = useState(false);
  17. const [timeSinceLastSave, setTimeSinceLastSave] = useState("");
  18. useImperativeHandle(ref, () => ({
  19. triggerSave: () => {
  20. setLastSaveTime(new Date());
  21. setShowSaved(true);
  22. },
  23. }));
  24. useEffect(() => {
  25. if (showSaved) {
  26. const timer = setTimeout(() => {
  27. setShowSaved(false);
  28. }, 10000);
  29. return () => clearTimeout(timer);
  30. }
  31. }, [showSaved]);
  32. useEffect(() => {
  33. const updateTimeSinceLastSave = () => {
  34. if (lastSaveTime) {
  35. const now = new Date();
  36. const diffInMinutes = Math.floor(
  37. (now.getTime() - lastSaveTime.getTime()) / 60000
  38. );
  39. if (diffInMinutes > 0) {
  40. setTimeSinceLastSave(`${diffInMinutes} 分钟前`);
  41. }
  42. }
  43. };
  44. const timer = setInterval(updateTimeSinceLastSave, 60000);
  45. updateTimeSinceLastSave(); // 立即更新一次
  46. return () => clearInterval(timer);
  47. }, [lastSaveTime]);
  48. return (
  49. <div className={className}>
  50. {showSaved && <span>已保存</span>}
  51. {!showSaved && lastSaveTime && (
  52. <span>最近修改:{timeSinceLastSave}</span>
  53. )}
  54. </div>
  55. );
  56. }
  57. );
  58. export default SaveStatus;