|
@@ -1,7 +1,7 @@
|
|
import React, { useEffect, useState } from "react";
|
|
import React, { useEffect, useState } from "react";
|
|
import { useAuth0, withAuthenticationRequired } from "@auth0/auth0-react";
|
|
import { useAuth0, withAuthenticationRequired } from "@auth0/auth0-react";
|
|
import Loading from "../Loading";
|
|
import Loading from "../Loading";
|
|
-import { IconButton } from "@material-ui/core";
|
|
|
|
|
|
+import { CircularProgress, IconButton } from "@material-ui/core";
|
|
import { PersonAdd, PersonAddDisabled } from "@material-ui/icons";
|
|
import { PersonAdd, PersonAddDisabled } from "@material-ui/icons";
|
|
import { makeStyles } from "@material-ui/styles";
|
|
import { makeStyles } from "@material-ui/styles";
|
|
import { array, bool, func, object } from "prop-types";
|
|
import { array, bool, func, object } from "prop-types";
|
|
@@ -18,33 +18,42 @@ const useStyles = makeStyles(theme => ({
|
|
backgroundColor: theme.palette.background.default,
|
|
backgroundColor: theme.palette.background.default,
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- addFriend: {
|
|
|
|
- color: theme.palette.primary.main,
|
|
|
|
- },
|
|
|
|
- removeFriend: {
|
|
|
|
- color: theme.palette.error.main,
|
|
|
|
- },
|
|
|
|
|
|
+ loadingCircle: {
|
|
|
|
+ position: 'absolute',
|
|
|
|
+ top: '50%',
|
|
|
|
+ left: '50%',
|
|
|
|
+ marginTop: '-12px',
|
|
|
|
+ marginLeft: '-12px',
|
|
|
|
+ }
|
|
}));
|
|
}));
|
|
|
|
|
|
/** Button that will toggle whether given contact is included in current user's contacts array. */
|
|
/** Button that will toggle whether given contact is included in current user's contacts array. */
|
|
const FriendOrUnfriendButton = (props) => {
|
|
const FriendOrUnfriendButton = (props) => {
|
|
const classes = useStyles();
|
|
const classes = useStyles();
|
|
- const { otherUser, afterUpdateContacts, contacts: givenContacts } = props;
|
|
|
|
|
|
+ const { otherUser, afterUpdateContacts, contacts: givenContacts, isSaving: isSavingSomething, setIsSaving: setIsSavingInParentComponent } = props;
|
|
const { user } = useAuth0();
|
|
const { user } = useAuth0();
|
|
|
|
|
|
const [contacts, setContacts] = useState(givenContacts);
|
|
const [contacts, setContacts] = useState(givenContacts);
|
|
const [isContact, setIsContact] = useState(false);
|
|
const [isContact, setIsContact] = useState(false);
|
|
|
|
+ const [isSavingThisOne, setIsSavingThisOne] = useState(false);
|
|
const [checkedIsContact, setCheckedIsContact] = useState(!!givenContacts);
|
|
const [checkedIsContact, setCheckedIsContact] = useState(!!givenContacts);
|
|
|
|
|
|
const updateContacts = (newContacts) => {
|
|
const updateContacts = (newContacts) => {
|
|
- if (user) {
|
|
|
|
|
|
+ if (user && !isSavingSomething && !isSavingThisOne) {
|
|
|
|
+ setIsSaving(true);
|
|
updateUserContacts(user.sub, newContacts, (updatedContacts) => {
|
|
updateUserContacts(user.sub, newContacts, (updatedContacts) => {
|
|
- if (afterUpdateContacts) afterUpdateContacts(updatedContacts);
|
|
|
|
|
|
+ setIsSaving(false);
|
|
|
|
+ if (afterUpdateContacts) afterUpdateContacts();
|
|
setContacts(updatedContacts);
|
|
setContacts(updatedContacts);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ const setIsSaving = (value) => {
|
|
|
|
+ setIsSavingThisOne(value);
|
|
|
|
+ if (setIsSavingInParentComponent) setIsSavingInParentComponent(value);
|
|
|
|
+ };
|
|
|
|
+
|
|
const fetchContacts = () => {
|
|
const fetchContacts = () => {
|
|
if (user) {
|
|
if (user) {
|
|
const userId = user.sub;
|
|
const userId = user.sub;
|
|
@@ -78,10 +87,13 @@ const FriendOrUnfriendButton = (props) => {
|
|
if (!checkedIsContact) return null;
|
|
if (!checkedIsContact) return null;
|
|
|
|
|
|
return (
|
|
return (
|
|
- <IconButton edge="end" className={(props.inCircle) ? classes.iconButtonInCircle : ''} onClick={() => isContact ? removeFriend() : addFriend()}>
|
|
|
|
|
|
+ <IconButton disabled={isSavingSomething || isSavingThisOne} edge="end" className={(props.inCircle) ? classes.iconButtonInCircle : ''} onClick={() => (isContact && !isSavingSomething) ? removeFriend() : addFriend()}>
|
|
{isContact
|
|
{isContact
|
|
- ? <PersonAddDisabled className={classes.removeFriend} />
|
|
|
|
- : <PersonAdd className={classes.addFriend} />}
|
|
|
|
|
|
+ ? <PersonAddDisabled color={isSavingSomething || isSavingThisOne ? "disabled" : "error"} />
|
|
|
|
+ : <PersonAdd color={isSavingSomething || isSavingThisOne ? "disabled" : "primary"} />}
|
|
|
|
+ {isSavingThisOne && (
|
|
|
|
+ <CircularProgress size={24} color="inherit" className={classes.loadingCircle} />
|
|
|
|
+ )}
|
|
</IconButton>
|
|
</IconButton>
|
|
);
|
|
);
|
|
}
|
|
}
|
|
@@ -95,12 +107,17 @@ FriendOrUnfriendButton.propTypes = {
|
|
contacts: array,
|
|
contacts: array,
|
|
/** optional styling that displays button in a white circle */
|
|
/** optional styling that displays button in a white circle */
|
|
inCircle: bool,
|
|
inCircle: bool,
|
|
|
|
+ /** optional styling that displays button in a white circle */
|
|
|
|
+ isSaving: bool,
|
|
|
|
+ /** function to change isSaving in parent component */
|
|
|
|
+ setIsSaving: func,
|
|
}
|
|
}
|
|
|
|
|
|
FriendOrUnfriendButton.defaultProps = {
|
|
FriendOrUnfriendButton.defaultProps = {
|
|
afterUpdateContacts: null,
|
|
afterUpdateContacts: null,
|
|
contacts: null,
|
|
contacts: null,
|
|
inCircle: false,
|
|
inCircle: false,
|
|
|
|
+ isSaving: false,
|
|
}
|
|
}
|
|
|
|
|
|
export default withAuthenticationRequired(FriendOrUnfriendButton, {
|
|
export default withAuthenticationRequired(FriendOrUnfriendButton, {
|