useUser.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import React from "react";
  2. import { useC2C } from "./useC2C";
  3. import randomColor from "randomcolor";
  4. import debounce from "lodash.debounce";
  5. import { atom, useRecoilState } from "recoil";
  6. const getUser = () => {
  7. if (localStorage.user) {
  8. const localUser = {
  9. name: "Player",
  10. color: randomColor({ luminosity: "dark" }),
  11. ...JSON.parse(localStorage.user),
  12. };
  13. // Id is given by server
  14. delete localUser.id;
  15. persistUser(localUser);
  16. return localUser;
  17. }
  18. const newUser = {
  19. name: "Player",
  20. color: randomColor({ luminosity: "dark" }),
  21. };
  22. persistUser(newUser);
  23. return newUser;
  24. };
  25. const persistUser = (user) => {
  26. localStorage.setItem("user", JSON.stringify(user));
  27. };
  28. export const userAtom = atom({
  29. key: "user",
  30. default: getUser(),
  31. });
  32. function useUser() {
  33. const [user, setUserState] = useRecoilState(userAtom);
  34. const [c2c, joined] = useC2C();
  35. React.useEffect(() => {
  36. if (joined) {
  37. setUserState((prevUser) => ({
  38. ...prevUser,
  39. id: c2c.userId,
  40. }));
  41. }
  42. }, [joined, c2c.userId, setUserState]);
  43. const setUser = React.useCallback(
  44. (newUser) => {
  45. setUserState((prevUser) => ({ ...newUser, id: prevUser.id }));
  46. persistUser(newUser);
  47. },
  48. [setUserState]
  49. );
  50. // eslint-disable-next-line react-hooks/exhaustive-deps
  51. const debouncedEmitUpdateUser = React.useCallback(
  52. debounce((newUser) => {
  53. c2c.publish("userUpdate", newUser, true);
  54. }, 500),
  55. [c2c]
  56. );
  57. React.useEffect(() => {
  58. if (user && user.id) {
  59. debouncedEmitUpdateUser(user);
  60. }
  61. }, [user, debouncedEmitUpdateUser]);
  62. return [user, setUser];
  63. }
  64. export default useUser;