-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHome.js
154 lines (134 loc) · 6.48 KB
/
Home.js
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import FileExplorer from "./FileExplorer";
import FileUpload from "./FileUpload";
import Profile from "./Profile";
import Contacts from "./Contacts";
import Albums from "./Albums";
import ContactDetails from "./ContactDetails";
import BottomNavBar from "./BottomNavBar";
import MenuBar from "./MenuBar";
import Notification from "./Notification";
import React, {useState} from "react";
import CircularProgress from '@material-ui/core/CircularProgress';
import { Switch, Route } from "react-router-dom";
/**
* The Home component handles the application logic and UI once logged-in to access the POD. The component
* relies on react router to switch between pages, with the root being the image gallery. The component
* also contains menu bars to interact with the content, and can display notifications and loading animations.
*
* @component
* @param {[type]} props [description]
*/
function Home(props) {
/**
* State containing notification messages.
*/
let [notifMsg, setNotifMsg] = useState("");
/**
* State containing the notification type, which should be a string value accepted
* by the material UI Alert component ("error", "info", "warning", "success").
*
* @see {@link https://material-ui.com/components/alert/}
*
*/
let [notifType, setNotifType] = useState("info");
/**
* Boolean state telling whether or not a loading animation is to be displayed.
*/
let [loadingAnim, setLoadingAnim] = useState(false);
/**
* State containing hidden routing parameters.
*/
let [routingHiddenParams, setRoutingHiddenParams] = useState([]);
/**
* State used to enable or disable the file select mode.
*/
let [fileSelectMode, setFileSelectMode] = useState(false);
/**
* State used to trigger a file delete operation for selected files.
*/
let [fileDeleteTriggered, setFileDeleteTriggered] = useState(false);
let webId = props.webId;
let podUrl = props.podUrl;
let explorerPath = props.explorerPath;
let setExplorerPath = props.setExplorerPath;
let history = props.history;
const classes = props.classes;
/**
* This function changes the route that should be taken by the router by appending
* the new path to the browser history, and cancels any loading animation running.
* Hidden parameters can also be passed to the function
* without being exposed in the url (displayed in the browser). This is particularly useful
* when the data contains sepcial characters that could mess with the routing (e.g. ':', '#' or '/')
* or when the parameter is too long and makes it difficult to debug the routing by looking at the
* browser url. Notice that if hiddenParams is not empty, it means that the page we want to load
* expects these parameters to be set beforehand, hence we first set the hidden parameters
* before initiating the page switch. On the other hand, if the hiddenParams is null,
* then we first want to render the new page before assigning null to the routingHiddenParams state.
* This is because the previous page might have a prop that references the routingHiddenParam state,
* hence setting it to null while the component is still there would generate an error.
* @param {[type]} screenPath The new path for the router, pushed to the history
* @param {[type]} hiddenParams Params that will be used by the new page, but don't go in the path url
*/
async function gotoScreen(screenPath, hiddenParams = null) {
// hiddenParams is defined and not null
// ==> update the state before moving to the new page
if (hiddenParams) {
await setRoutingHiddenParams(hiddenParams);
}
await setLoadingAnim(false); // always cancel loading anim when switching screen
history.push(`${screenPath}`);
// hiddenParams is null, so we set it after the page change
if (! hiddenParams) {
await setRoutingHiddenParams(null);
}
}
/**
* Displays a fixed loading animation centered on the screen when the loadingAnim state is set to true.
* The animation is top level, hence it has a z-index higher than the other components, and it floats
* as the user scrolls the page.
*
* @see {@link https://material-ui.com/api/circular-progress/}
* @return {[CircularProgress]} A styled material-ui CircularProgress element
*/
function showLoadingAnimation() {
if (loadingAnim) {
return <CircularProgress color="secondary" size={100}
style={{zIndex: 1700, opacity: ".7", position: "fixed", top: "45vh"}}/>
}
}
return (<>
{showLoadingAnimation()}
<MenuBar classes={classes} history={history} gotoScreen={gotoScreen}
fileSelectMode={fileSelectMode} setFileSelectMode={setFileSelectMode}
setFileDeleteTriggered={setFileDeleteTriggered}/>
<Notification setNotifMsg={setNotifMsg} notifMsg={notifMsg} notifType={notifType}/>
<div className="content">
<Switch>
<Route exact path="/upload">
<FileUpload explorerPath={explorerPath} setNotifMsg={setNotifMsg}
setNotifType={setNotifType} setLoadingAnim={setLoadingAnim}/>
</Route>
<Route exact path="/profile">
<Profile webId={webId} podUrl={podUrl}/>
</Route>
<Route exact path="/contacts">
<Contacts gotoScreen={gotoScreen} podUrl={podUrl}/>
</Route>
<Route path="/contacts/:username"
render={(props) => <ContactDetails routingHiddenParams={routingHiddenParams} realProps={props}/>}/>
<Route exact path="/albums">
<Albums/>
</Route>
<Route exact path="/">
<FileExplorer podUrl={podUrl} explorerPath={explorerPath}
setExplorerPath={setExplorerPath} setLoadingAnim={setLoadingAnim}
fileSelectMode={fileSelectMode}
fileDeleteTriggered={fileDeleteTriggered} setFileDeleteTriggered={setFileDeleteTriggered}
setNotifMsg={setNotifMsg} setNotifType={setNotifType}/>
</Route>
</Switch>
</div>
<BottomNavBar classes={classes} gotoScreen={gotoScreen}/>
</>);
}
export default Home;