Skip to main content
Glama
deso-protocol

DeSo MCP Server

Official
user-account-list.tsx5.01 kB
import { MenuItem } from "@material-tailwind/react"; import { getUsersStateless, identity, User } from "deso-protocol"; import { Identity } from "deso-protocol/src/identity/identity"; import orderBy from "lodash/orderBy"; import { useContext, useEffect, useState } from "react"; import { ClipLoader } from "react-spinners"; import { toast } from "react-toastify"; import { UserContext } from "../contexts/UserContext"; import { formatDisplayName } from "../utils/helpers"; import { MessagingDisplayAvatar } from "./messaging-display-avatar"; const COLLAPSED_ACCOUNTS_NUM = 3; const EXPANDED_ACCOUNTS_NUM = 10; const ACCOUNT_LIST_ITEM_HEIGHT_PX = 30; type Account = { name: string; onclick: (key: string) => void; key: string; profile: User; hasProfile: boolean; isActive: boolean; }; const UserAccountList = () => { const { appUser } = useContext(UserContext); const [showMore, setShowMore] = useState<boolean>(false); const [users, setUsers] = useState<User[]>([]); const [allAccounts, setAllAccounts] = useState<Account[]>([]); const [loading, setLoading] = useState(false); useEffect(() => { const fetchLoggedInUsers = async (loggedInUserKeys: Array<string>) => { if (loggedInUserKeys.length === 0) { return; } setLoading(true); try { const res = await getUsersStateless({ PublicKeysBase58Check: loggedInUserKeys, SkipForLeaderboard: true, }); if (res.UserList) { setUsers(res.UserList); } } catch (e) { toast.error(`Error fetching user profiles: ${e}`); console.error(e); } finally { setLoading(false); } }; const snapshot = (identity as Identity<Storage>).snapshot(); const activeUser = snapshot.currentUser; const alternateUsers = Object.keys(snapshot.alternateUsers || {}); const loggedInUserKeys = [ ...(activeUser ? [activeUser.publicKey] : []), ...alternateUsers, ]; setUsers( loggedInUserKeys.map((key) => ({ PublicKeyBase58Check: key, })) as User[] ); fetchLoggedInUsers(loggedInUserKeys); }, [appUser]); useEffect(() => { const accounts = (users || []).map((user) => { const key = user.PublicKeyBase58Check; const isActive = key === appUser?.PublicKeyBase58Check; const profile = isActive && appUser ? appUser : user; const hasProfile = !!profile; return { name: formatDisplayName(user, ""), onclick: async (key: string) => identity.setActiveUser(key), key, profile, hasProfile, isActive, }; }); const sortedAccounts = orderBy( accounts, ["isActive", "hasProfile", "name"], ["desc", "desc", "asc"] ); setAllAccounts(sortedAccounts); }, [users, appUser]); const visibleAccounts = showMore ? allAccounts : allAccounts.slice(0, COLLAPSED_ACCOUNTS_NUM); return ( <div className={`mb-0 ${ loading || visibleAccounts.length > 0 ? "border-b" : "" }`} > {loading ? ( <div className="flex justify-center my-2 h-[29px]"> <ClipLoader color={"#0d3679"} loading={true} size={24} /> </div> ) : ( <> <section className="text-gray-700 custom-scrollbar" aria-labelledby="dropdownInformationButton" style={ showMore ? { maxHeight: `${ EXPANDED_ACCOUNTS_NUM * ACCOUNT_LIST_ITEM_HEIGHT_PX }px`, overflowY: "scroll", } : {} } > {visibleAccounts.map((option) => { return ( <MenuItem key={option.key} onClick={() => option.onclick(option.key)} className="cursor-pointer text-md pl-2" > <div className={`flex items-center ${ option.isActive ? "font-bold" : "" }`} > <MessagingDisplayAvatar publicKey={option.key} username={option.name} classNames="mr-2 ml-0" diameter={28} /> <div className="truncate text-base">{option.name}</div> </div> </MenuItem> ); })} </section> {!showMore && allAccounts.length > COLLAPSED_ACCOUNTS_NUM && ( <span className="text-blue-600 text-sm text-left mx-3 mt-2 mb-3 block cursor-pointer" onClick={(e) => { e.stopPropagation(); setShowMore(true); }} > Show more </span> )} </> )} </div> ); }; export { UserAccountList };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/deso-protocol/deso-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server