CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/lib/hooks/profile.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
// Hook that uses API to get a given user's profile.
7
//
8
// If account_id is explicitly given, returns the *public* profile for that users.
9
//
10
// If account_id is NOT given, returns the *private* profile for the signed in user, or
11
// empty object if user not signed in.
12
13
import LRU from "lru-cache";
14
import { useEffect, useState } from "react";
15
16
import { Profile } from "@cocalc/server/accounts/profile/types";
17
import { len } from "@cocalc/util/misc";
18
import apiPost from "lib/api/post";
19
import useIsMounted from "./mounted";
20
21
// How often to check for new profile.
22
const DEFAULT_CACHE_S = 10;
23
24
// This cache is to avoid flicker when navigating around, since
25
// we want to show the last known avatar for a given user before
26
// checking if there is a new one.
27
const cache = new LRU<string, Profile>({ max: 300 });
28
29
interface Options {
30
noCache?: boolean;
31
account_id?: string;
32
}
33
34
export default function useProfile(opts: Options = {}): Profile | undefined {
35
const { profile } = useProfileWithReload(opts);
36
return profile;
37
}
38
39
export function useProfileWithReload(opts: Options = {}): {
40
profile: Profile | undefined;
41
reload: () => void;
42
} {
43
const { account_id, noCache } = opts;
44
const isMounted = useIsMounted();
45
const [profile, setProfile] = useState<Profile | undefined>(
46
noCache ? undefined : cache.get(account_id ?? "")
47
);
48
49
async function getProfile(): Promise<void> {
50
try {
51
const { profile } = await apiPost(
52
"/accounts/profile",
53
{ account_id, noCache },
54
DEFAULT_CACHE_S
55
);
56
if (!isMounted.current) return;
57
setProfile(profile);
58
if (!noCache && len(profile) > 0) {
59
// only cache if got actual information.
60
cache.set(account_id ?? "", profile);
61
}
62
} catch (err) {
63
console.warn("Unable to fetch a profile -- ", err);
64
}
65
}
66
67
useEffect(() => {
68
getProfile();
69
}, [account_id, noCache]);
70
71
return { profile, reload: getProfile };
72
}
73
74