const accountId = context.accountId; // fixme! our VM removes the query params from the url // fixme! so we need to cache them before the second render // fixme! https://github.com/calimero-is-near/VM/pull/165 const cachedParams = useRef(null); // todo! drop this cache when the VM is patched, if it ever is cachedParams.current = { ...cachedParams.current, ...extractQueryParams() }; const props = { ...props, ...cachedParams.current }; const initialContract = props.contract || 'chat-staging.ws-protocol-63'; const componentOwnerId = props.componentOwnerId || 'calimero.testnet'; const encryptionUrl = props.encryptionUrl || 'https://cali-encryption.euw3.staging.gcp.calimero.network/key'; const meroshipUrl = props.meroshipUrl || 'wss://api.staging.calimero.network/api/v1/shards/ws-protocol-63-calimero-testnet/meroship/ws'; const enableCommunities = props.enableCommunities ?? false; const onAppJoined = props.onAppJoined || (() => {}); const onAppJoin = props.onAppJoin || (() => {}); const communities = props.communities || []; const getCalimeroToken = props.getCalimeroToken || (() => {}); const refresh = props.refresh || (() => {}); const debug = props.debug || false; const getSelectedCommunity = useCallback(() => { return Storage.innerGet('community').then((value) => { if (!value) { value = initialContract; Storage.set('community', value); } setContract(value); }); }, [initialContract]); const [contract, setContract] = useState(null); const [loggedIn, setLoggedIn] = useState(false); const [initialChat, setInitialChat] = useState(null); const handleContractChange = useCallback((contract) => { changeContract(contract, null); }, []); const updateInitialChat = useCallback((session) => { Storage.set('lastSession', JSON.stringify(session)); }, []); function changeContract(contract, session) { Storage.set('community', contract); setContract(contract); setLoggedIn(false); updateInitialChat(session); } const getUrlSession = () => { const urlDerivedChatParams = cachedParams.current; let derivedSession = null; if ( urlDerivedChatParams && urlDerivedChatParams.type && urlDerivedChatParams.target && urlDerivedChatParams.contractName ) { if (!communities.includes(urlDerivedChatParams.contractName)) { console.log('Error unknown contract id on push notif.'); return; } if (urlDerivedChatParams.type === 'channel') { derivedSession = { type: urlDerivedChatParams.type, name: urlDerivedChatParams.target, }; } else if (urlDerivedChatParams.type === 'dm') { derivedSession = { type: 'direct_message', id: urlDerivedChatParams.target, }; } changeContract(urlDerivedChatParams.contractName, derivedSession); } return derivedSession; }; const getInitialChat = useCallback(async () => { const derivedSession = getUrlSession(); if (derivedSession) { setInitialChat(derivedSession); return; } Storage.innerGet('lastSession').then((session) => { setInitialChat(session ? JSON.parse(session) : null); }); }, []); useEffect(() => { getSelectedCommunity(); getInitialChat(); }, []); if (!contract) { return 'Loading'; } const PageContainer = styled.div` height: 100%; width: 100%; `; const loginApi = useMemo( () => ({ join: () => { onAppJoin(); Near.fakCalimeroCall(contract, 'join'); }, login: () => { onAppJoin(); Near.requestCalimeroFak(contract); }, validateKey: () => Near.hasValidCalimeroFak(contract), getMembers: () => Near.asyncCalimeroView(contract, 'get_members'), }), [contract], ); const Logo = () => ( <Widget src={`${componentOwnerId}/widget/Calimero.Curb.Navbar.CurbLogo`} props={{ justify: true, }} /> ); // Ping to prepare the new key, needs to be simplified const ping = () => Near.fakCalimeroCall(contract, 'ping'); const App = (props) => ( <Widget src={`${componentOwnerId}/widget/Calimero.Curb.Logger`} props={{ debug, render: ({ Logger }) => ( <Widget src={`${componentOwnerId}/widget/Calimero.Curb.EventEmitter`} props={{ render: ({ EventEmitter }) => ( <Widget src={`${componentOwnerId}/widget/Calimero.Curb.WebSocketManager`} props={{ deps: { Logger, EventEmitter }, debug, accountId: props.accountId, wsAddress: meroshipUrl, getAuthToken: getCalimeroToken, render: ({ wsApi }) => ( <Widget src={`${componentOwnerId}/widget/Calimero.Curb.AppContainer`} props={{ ...props, wsApi, deps: { Logger, EventEmitter }, }} /> ), }} /> ), }} /> ), }} /> ); return ( <PageContainer> {!loggedIn || !accountId ? ( <Widget src={`${componentOwnerId}/widget/Calimero.Common.Login.index`} props={{ loginApi, accountId, componentOwnerId, onValidLogin: () => { onAppJoined(accountId); // todo! migrate to meroship ping().then(() => { setLoggedIn(true); }); }, logo: <Logo />, onAppJoin, refresh, }} /> ) : ( <App componentOwnerId={componentOwnerId} contract={contract} encryptionUrl={encryptionUrl} accountId={accountId} enableCommunities={enableCommunities} handleContractChange={handleContractChange} initialChat={initialChat} updateInitialChat={updateInitialChat} communities={communities} /> )} </PageContainer> );