-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathuseProjectPersistence.js
More file actions
113 lines (105 loc) · 3.33 KB
/
Copy pathuseProjectPersistence.js
File metadata and controls
113 lines (105 loc) · 3.33 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { isOwner } from "../utils/projectHelpers";
import {
expireJustLoaded,
setHasShownSavePrompt,
syncProject,
} from "../redux/EditorSlice";
import { showLoginPrompt, showSavePrompt } from "../utils/Notifications";
const COMBINED_FILE_SIZE_SOFT_LIMIT = 1000000;
export const useProjectPersistence = ({
user,
project = {},
justLoaded,
hasShownSavePrompt,
saveTriggered,
reactAppApiEndpoint,
loadRemix = true,
}) => {
const dispatch = useDispatch();
const combinedFileSize = project.components?.reduce(
(sum, component) => sum + component.content.length,
0,
);
const autoSaveInterval =
combinedFileSize > COMBINED_FILE_SIZE_SOFT_LIMIT ? 10000 : 2000;
const saveToLocalStorage = (project) => {
localStorage.setItem(
project.identifier || "project",
JSON.stringify(project),
);
};
useEffect(() => {
const saveProject = async () => {
if (Object.keys(project).length !== 0) {
const identifier = project?.identifier;
const accessToken = user?.access_token;
const params = { reactAppApiEndpoint, accessToken };
if (saveTriggered || localStorage.getItem("awaitingSave")) {
if (isOwner(user, project)) {
await dispatch(
syncProject("save")({ ...params, project, autosave: false }),
);
localStorage.removeItem("awaitingSave");
} else if (user && identifier) {
await dispatch(
syncProject("remix")({
...params,
project: {
...project,
image_list: project.image_list.map((image) => ({
...image,
content: image.content,
})),
},
}),
);
if (loadRemix) {
// Ensure the remixed project is loaded, otherwise we'll get in a mess
await dispatch(
syncProject("loadRemix")({
...params,
identifier,
}),
);
}
}
}
}
};
saveProject();
}, [saveTriggered, project, user, dispatch, reactAppApiEndpoint, loadRemix]);
useEffect(() => {
let debouncer = setTimeout(() => {
if (project) {
if (isOwner(user, project) && project.identifier) {
if (justLoaded) {
dispatch(expireJustLoaded());
}
dispatch(
syncProject("save")({
reactAppApiEndpoint,
project,
accessToken: user.access_token,
autosave: true,
}),
);
} else {
if (justLoaded) {
dispatch(expireJustLoaded());
} else {
if (!hasShownSavePrompt) {
user ? showSavePrompt() : showLoginPrompt();
dispatch(setHasShownSavePrompt());
}
}
saveToLocalStorage(project);
}
}
}, autoSaveInterval);
return () => clearTimeout(debouncer);
}, [dispatch, project, user, hasShownSavePrompt]); // eslint-disable-line react-hooks/exhaustive-deps
// Disabling exhasutive dependencies linting rule because adding justLoaded to the dependency array
// triggers the save/login prompt too early
};