// import "./styles/UserWidget.less"; import { Avatar, Button, Col, Input, List, Modal, Row, Slider, Tooltip } from "antd"; import { BlockExplorerLink } from "../Components/Links"; import { Callback, IOView, NLView } from "../types"; import { ContentImage } from "../Components/Image"; import { CrossCircle } from "../Components/Icons/CrossCircle"; import { DAO } from "../Components/Icons/DAO"; import { DataRow } from "../Components/DataRow"; import { Edit } from "../Components/Icons/Edit"; import { HashDisplay } from "../Components/CryptoEntities"; import { IBadge } from "../hooks/useBadges"; import { ItemGrid } from "../Components/ItemGrid"; import { Link, useHistory, useParams } from "react-router-dom"; import { NewcoinRecept } from "../Components/Recepts"; import { Polygon } from "../Components/Icons/Polygon"; import { PowerupsCacheItem } from "../overmind/api/state"; import { ProgressButton } from "../Components/ProgressButton"; import { RevealInfo } from "../Components/RevealInfo"; import { STAKE_STEPS, STAKE_STEPS_TYPE } from "../overmind/flows/stake/state"; import { ScrollMenu } from "react-horizontal-scrolling-menu"; import { Smallinfo } from "../Components/Icons/Smallinfo"; import { SocialLink } from "../Components/SocialLink"; import { UserFlowRoutes } from "../Pages/User/User"; import { UserReadPrivateResponse, UserReadPublicResponse } from "@newstackdev/iosdk-newgraph-client-js"; import { UserSocials } from "../Pages/User/interfaces/IUser"; import { VerifiedIcon } from "../Components/Icons/VerifiedIcon"; import { showPopUp } from "../utils/popup"; import { useActions, useAppState } from "../overmind"; import { useCachedDaoProposals } from "../hooks/useCached"; import { useCachedPool, useCachedPowerups, useCachedUser } from "../hooks/useCached"; import { useEffect, useState } from "react"; import { useVerified } from "../hooks/useVerified"; import BadgeWidget from "./BadgeWidget"; import CountUp from "react-countup"; import Paragraph from "antd/lib/typography/Paragraph"; import PowerupDialog from "../Components/PowerupDialog"; import ShowMoreText from "react-show-more-text"; import isFinite from "lodash/isFinite"; import usePreventBodyScroll from "../hooks/usePreventBodyScroll"; const ellipsisStyle = { maxWidth: 125, whiteSpace: "nowrap", textOverflow: "ellipsis", overflow: "hidden", } as const; export const SOCIAL_MEDIA = [ UserSocials.SOUNDCLOUD, UserSocials.INSTAGRAM, UserSocials.TWITTER, UserSocials.FACEBOOK, UserSocials.PINTEREST, UserSocials.TUMBLR, UserSocials.YOUTUBE, UserSocials.DISCORD, ]; export const UserWidgetVertical: NLView<{ user?: UserReadPublicResponse }> = ({ user }) => { const u = useCachedUser({ id: user?.id || "" }); if (!u) return <>; return (
Stake on {u.username}
); }; const round = (v: number) => Math.round(v * 1000) / 1000; /** * User stake widget. * @param * @returns */ export const UserStake: NLView<{ user?: UserReadPrivateResponse; mode?: STAKE_STEPS_TYPE; value?: number; minValue?: number; hideButton?: boolean; hideSelect?: boolean; buttonText?: string; closeOnDone?: boolean; onDone?: Callback; onCancel?: Callback; usePowerupTerminology?: boolean; stakeInNewsafe?: boolean; }> = ({ user, mode, value, minValue, hideButton, buttonText, hideSelect, closeOnDone, onDone, onCancel, usePowerupTerminology = false, stakeInNewsafe, }) => { // const [visible, setVisible] = useState(false); const actions = useActions(); const poolInfo = useCachedPool({ owner: user?.username, code: user?.newcoinTicker }); const [preStakeValue, setPrestakeValue] = useState(0); const [_value, setValue] = useState(value || 100); const [fee, setFee] = useState(0.08 * _value); const state = useAppState(); const [tx, setTx] = useState(""); const [_mode, setMode] = useState(mode ?? STAKE_STEPS.DISABLED); const _user = useCachedUser(user, true); const balances = state.newcoin.mainPool?.acc_balances || []; //state.newcoin.account?.acc_balances || []; const ncoBalance = Number((balances[0] || "").replace(/ GNCO$/, "")); const membershipValue = state.newcoin.pools[poolInfo.code]; const displayMembershipValue = membershipValue; minValue = minValue || 100; const stakeDelta = (membershipValue || 0) - (preStakeValue || 0); const hasDao = !!poolInfo.code; // && /\.(io|nco)$/.test(user?.username || ""); const closeWallet = () => actions.flows.userJourney.setFlag({ flag: "walletShown", value: "", }); useEffect(() => { setMode(mode ?? STAKE_STEPS.DISABLED); }, [mode]); useEffect(() => { const m = _mode ?? STAKE_STEPS.DISABLED; setMode(m); actions.flows.stake.setLatestMode({ stakingMode: m }); }, [_mode]); useEffect(() => { !hasDao && _mode >= 0 && setMode(STAKE_STEPS.NODAO); }, [hasDao, _mode]); const updateValue = (v: number) => { setValue(v); setFee(round(0.08 * v)); }; const stake = async () => { setPrestakeValue(membershipValue); const res = await actions.api.user.stake({ user: _user, amount: _value + ".0000", }); const historyItem = [...state.api.cache.stakeHistory].reverse().find((h) => h.user.username === user?.username); const success = !!res.TxID_stakePool; //historyItem && !historyItem.error; success && setTx(res.TxID_stakePool); setMode(success && closeOnDone ? STAKE_STEPS.DISABLED : STAKE_STEPS.DONE); }; const startStaking = () => { setMode(STAKE_STEPS.SELECT); }; return ( <> } // getContainer={getContainer} visible={_mode == STAKE_STEPS.NODAO} cancelText="Ok" // onCancel={() => setMode(STAKE_STEPS.SELECT)} onCancel={() => { setMode(STAKE_STEPS.DISABLED); onDone && onDone({}); }} okButtonProps={{ style: { display: "none" } }} wrapClassName="iosdk-modal iosdk-stake-modal" className="iosdk-modal iosdk-stake-modal nl-white-box-modal" > } />

{_user.username}

has not created their DAO yet.
Please check this profile later. stake()} closeIcon={} onCancel={() => { setMode(hideButton ? STAKE_STEPS.DISABLED : STAKE_STEPS.SELECT); }} footer={false} className="nl-white-box-modal primary-buttons-modal" > } /> {membershipValue > 0 ? (

{/* Join {_user?.username || ""}'s DAO */} Your membership in {poolInfo.owner.toUpperCase()} DAO is at {displayMembershipValue}. Stake {_value} GNCO more to increase your membership value.

) : (

Join {_user?.username || ""}'s DAO

)}

Are you sure you want to {membershipValue ? ( <> {" "} increase your stake in {_user?.username || ""}'s DAO by {_value} $GNCO ) : ( <> {" "} stake {_value} $GNCO to join {_user?.username || ""} 's DAO? )} ?
You will deposit {_value} $GNCO and pay a {round(fee)} $GNCO fee.

{/* to get your 1000 ${(_user?.username || "").toUpperCase()}. */} { stake(); }} > Confirm

This is only on Testnet! Need help?
Join our telegram group!

id
= STAKE_STEPS.SELECT && !hideSelect} okText={"Close"} footer={false} onCancel={() => { _mode === STAKE_STEPS.DONE ? onDone && onDone() : onCancel && onCancel(); setMode(STAKE_STEPS.DISABLED); }} className="nl-white-box-modal" closeIcon={} > } />

{membershipValue > 0 ? ( <> Your {usePowerupTerminology ? "powerup" : "stake"} in {poolInfo.code || ""} is ${displayMembershipValue} $ {poolInfo.owner.toUpperCase()}. {usePowerupTerminology ? "Powerup" : "Stake"} {_value} GNCO more to increase your membership value. ) : ( <>Join {_user?.username || ""}'s DAO )}

setValue(Number(e.target.value))} value={_value} suffix="$GNCO" className="gnco_input" />
{Math.round(fee * 100) / 100} $GNCO Fee

This is only on Testnet! Need help?
Join our telegram group!

{/* Test modal */} { setMode(STAKE_STEPS.DISABLED); onDone && onDone({ preStakeValue, stakeValue: _value, stakeDelta, }); }} >

Congratulations

{preStakeValue ? ( <> Your stake in {_user?.username}'s DAO increased by {stakeDelta} {poolInfo.code}. ) : ( <>You are now a member of the {_user?.username}'s DAO with all the rights and duties associated. )}

{_value} $GNCO
— {round((fee * 5) / 8)} $GNCO (5%) creator fee
— {round((fee * 3) / 8)} $GNCO (3%) DAO fee

{round(_value - fee)} $GNCO

{hideButton ? ( "" ) : stakeInNewsafe ? ( ) : ( { closeWallet(); startStaking(); }} progressText="Staking..." type="primary" > {buttonText || "Stake"} )} ); }; export const UserPowerup: NLView<{ user?: UserReadPrivateResponse }> = ({ user }) => { const [visible, setVisible] = useState(false); const actions = useActions(); const state = useAppState(); const history = useHistory(); const { verifiedUsers } = useVerified([user?.username || ""]); const isUserVerified = verifiedUsers && user?.username && verifiedUsers.includes(user.username); const [stakeMode, setStakeMode] = useState(false); const currentUserPowerups: PowerupsCacheItem = useCachedPowerups() as any; const poolInfo = useCachedPool({ owner: user?.username }); const membershipValue = state.newcoin.pools[poolInfo.code]; const rating = currentUserPowerups?.out?.value?.find((u) => u.id === user?.id); const isPowering = !!rating; const timeSince = rating?.rating?.created ? Date.now() - new Date(rating?.rating?.created).getDate() : -1; const powerup = async () => { setVisible(true); !isPowering && user && (await actions.api.user.powerup({ user, amount: 1 })); }; const toStakeMode = () => { setStakeMode(true); // setVisible(false); }; useEffect(() => { if (!visible) setStakeMode(false); }, [visible]); const myProfileUrl = `/user/${state.api.auth.user?.username}`; // () => actions.routing.historyPush({ location: `/user/stake/${u.id}` }) return ( <> setVisible(false)} onCancel={() => setVisible(false)} cancelButtonProps={{ hidden: true }} footer={false} className="iosdk-modal nl-white-box-modal" closeIcon={} >
} />
{isPowering && timeSince > 60000 ? "You powered" : state.indicators.specific["api.user.powerup"] ? "Powering..." : ""}
{user?.username} {isUserVerified && }
+1

Multiply your power up

This is only on Testnet! Need help?
Join our telegram group!

{/* {myProfileUrl === history.location.pathname && ( )} */} setStakeMode(false)} onDone={() => { setVisible(false); setStakeMode(false); }} hideButton={true} user={user} mode={stakeMode ? STAKE_STEPS.SELECT : STAKE_STEPS.DISABLED} /> ); }; export const UserWidgetTopFixed: NLView<{ user?: UserReadPrivateResponse }> = ({ user }) => { return (
{user?.username}
); }; export const UserWidgetHeading: NLView<{ user?: UserReadPrivateResponse; setActiveKey?: React.Dispatch>; setShowSocials?: React.Dispatch>; activeKey?: UserFlowRoutes; newPowerup?: boolean; hideNewlifeSpecificInfo?: boolean; disableBadges?: boolean; isBadgesLoading?: boolean; badgesError?: string; badges?: IBadge[]; }> = ({ user, setActiveKey, newPowerup = true, hideNewlifeSpecificInfo = false, disableBadges, isBadgesLoading, badgesError, badges, }) => { const u = useCachedUser({ username: user?.username }, true); const state = useAppState(); const actions = useActions(); const params = useParams<{ username: string; id: string }>(); const { verifiedUsers } = useVerified([user?.username || ""]); const isUserVerified = verifiedUsers && u.username && verifiedUsers.includes(u.username); const poolInfo = useCachedPool({ owner: user?.username }); const daoOwner = params.username || state.config.settings.newcoin.daoDomain; const daoProposals = useCachedDaoProposals({ daoOwner }); if (!user) return <>; const toMonthName = (monthNumber: number) => { const date = new Date(); date.setMonth(monthNumber - 1); return date.toLocaleString("en-US", { month: "long", }); }; const getSortedSocialMediaIcons = () => { const sortedSocials = [...SOCIAL_MEDIA].sort((a, b) => { if (user.verifiedSocialIds?.includes(a)) { return -1; } return 0; }); return sortedSocials.map((social) => ); }; const monthNumber = new Date(user.created || "").getMonth(); const fullYear = new Date(user.created || "").getFullYear(); const joinedDate = "Joined " + toMonthName(monthNumber) + " " + fullYear; const isCurrentUserProfile = u.id === state.api.auth.user?.id; return ( setActiveKey && setActiveKey("Folders")} style={{ cursor: "pointer" }}> } style={{ width: "160px", height: "160px" }} /> setActiveKey && setActiveKey("Folders")} style={{ cursor: "pointer" }}>

{u.username}

{isUserVerified && } {isCurrentUserProfile && ( )}

{user.displayName}

{getSortedSocialMediaIcons()}

Show more} less={Show less} className="content-css" anchorClass="my-anchor-css-class" expanded={false} width={280} truncatedEndingComponent={" "} > {user.description}

{joinedDate}

setActiveKey && setActiveKey("UserDetail")} className="user-widget-heading__powerup-number">

{/**remove when interface has been updated */} {/**@ts-ignore*/}

Watts

setActiveKey && setActiveKey("UserDetail")} className="user-widget-heading__powerup-number u-margin-right-small" > {!disableBadges && ( )} {newPowerup ? : } {(daoProposals.dao_id || isCurrentUserProfile) && !hideNewlifeSpecificInfo && ( )}
); }; export const UserSocialInfo: NLView<{ user?: UserReadPrivateResponse }> = ({ user }) => ( (user as any)[k])} renderItem={(k) => { return ( } /> ); }} /> ); export const UsersList: NLView<{ users?: UserReadPrivateResponse[]; powerUp?: boolean; title?: string; layout?: "horizontal" | "vertical"; }> = ({ users, powerUp, title, layout }) => ( <> {title ?

{title}

: ""} { return ( } />} description={ {u.username} {u.powered || ""} } /> ); }} /> ); // // header="Activity Stream" // items={users || []} // render={(u: UserReadPublicResponse) => { const sliderStyle = { height: "160px", color: "#fff", lineHeight: "160px", background: "#364d79", padding: 12, width: "min(100%,300px)", }; export const UsersHorizontalScroller: NLView<{ users?: UserReadPrivateResponse[]; powerUp?: boolean; title?: string; layout?: "horizontal" | "vertical"; }> = ({ users, powerUp, title, layout }) => { const { disableScroll, enableScroll } = usePreventBodyScroll(); return (
{title ?

{title}

: ""} } RightArrow={} > {/* */} {users?.map((u, i) => { return ( } /> {u.username}

{u.powered || ""}
); }) || <>} {/*
*/}
); }; export const UsersGrid: NLView<{ users?: UserReadPrivateResponse[]; powerUp?: boolean; title?: string; layout?: "horizontal" | "vertical"; }> = ({ users, powerUp, title, layout }) => ( <> {title ?

{title}

: ""} { return ( } /> {u.username}

{u.powered || ""}
); }} /> ); export const UserSocialInfoRow: NLView<{ user?: UserReadPrivateResponse }> = ({ user }) => ( <> {"instagram,soundcloud,twitter,facebook,pinterest,tumblr" //,phone,status" .split(/,/) .filter((k) => (user as any)[k]) .map((k) => ( ))} ); export const PoolInfoDataRow: NLView<{ pool?: { code: string }; verifyIconLight?: boolean; noLink?: boolean; stakeInNewsafe?: boolean; }> = ({ pool, verifyIconLight = false, noLink, stakeInNewsafe }) => { const poolInfo = useCachedPool(pool); const myPools = useAppState().newcoin.pools; const user = useCachedUser({ username: poolInfo.owner }); const { verifiedUsers } = useVerified([user.username || ""]); const isUserVerified = verifiedUsers && user.username && verifiedUsers.includes(user.username); const state = useAppState(); const row = ( } className="avatar-image-small" />
{user.username} {isUserVerified ? ( verifyIconLight ? ( ) : ( ) ) : ( false )}
${poolInfo.code?.toUpperCase()}  {~~myPools[poolInfo?.code]}
TVL: {poolInfo.total.quantity} {/* {Math.round(Number(poolInfo?.total.quantity.toString().replace(/NCO/, "")))} */}
); return noLink ? <>{row} : {row}; //
// // {pool?.code} ${myPools[poolInfo?.code]} ${poolInfo?.code} // / ${poolInfo?.total.quantity } //
// {poolInfo?.owner} // // } // value={ // `${pool?.code} ${myPools[poolInfo?.code]} ${poolInfo?.code // } // / ${poolInfo?.total.quantity // }`} // link={`/user/${poolInfo?.owner}`} // target="" // /> // ); // <>${poolInfo?.owner} {JSON.stringify(poolInfo)}; }; export const UserNewcoinPoolsParticipation: IOView<{ user?: UserReadPrivateResponse; onStakeStart?: Callback; isWalletUsage?: boolean; }> = ({ user = {}, onStakeStart, isWalletUsage = false }) => { const nc = useAppState().newcoin; return ( <>

Your DAO Memberships

{Object.keys(nc.pools).map( (code) => ( ), // } // value={`${val as string} ${code}`} // /> )} ); }; export const UserNewcoinInfo: NLView<{ user?: UserReadPrivateResponse }> = ({ user = {} }) => { const state = useAppState(); const { verifiedUsers } = useVerified([user.username || ""]); const isUserVerified = verifiedUsers && user.username && verifiedUsers.includes(user.username); const poolInfo = useCachedPool({ owner: user?.username }); return ( <> {user.username}
) : ( user.username ) } link={`https://explorer-dev.newcoin.org/account/${user.username}`} collapse={true} /> } collapse={true} /> } collapse={true} /> } collapse={true} /> } collapse={true} /> ); }; export const UserPrivateInfo: NLView<{ user?: UserReadPrivateResponse }> = ({ user }) => ( <> {user && "instagram,soundcloud,twitter,facebook,pinterest,phone,status" .split(/,/) .filter((k) => (user as any)[k]) .map((k) => { return ( {user.firstName} {user.lastName} {user.fullName} ); })} );