import init, { encrypt_or_decrypt_files2, password, sanitize_base64, base64_to_vec,vec_to_base64, uuid_generate, encode_base64 } from 'my-crate'; import './style.css' import $ from 'jquery'; import iro from '@jaames/iro'; import Plyr from 'plyr'; import { Polybase } from "@polybase/client"; import Recorder from "yiyi-audio-recorder"; import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-generator'; import { Connection, Keypair, PublicKey, sendAndConfirmTransaction, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; import { Buffer } from 'buffer'; window.Buffer = Buffer; // import * as algosdk from 'algosdk'; // import { use} from "@maticnetwork/maticjs" // import { Web3ClientPlugin } from '@maticnetwork/maticjs-ethers' // import { ethers } from 'ethers'; // import { createWeb3Modal, defaultWagmiConfig } from '@web3modal/wagmi'; // import { polygonZkEvm } from '@wagmi/core/chains'; // import { watchAccount, disconnect, getAccount } from '@wagmi/core' // import { ArweaveWebWallet } from 'arweave-wallet-connector' // import Arweave from 'arweave'; // const arweave = Arweave.init({ // host: 'arweave.net', // Hostname or IP address for a Arweave host // port: 443, // Port // protocol: 'https', // Network protocol http or https // timeout: 20000, // Network request timeouts in milliseconds // logging: false, // Enable network request logging // }); $('#overlay_algo_gate').hide(); $('#algo_gate').hide(); $('#chats_title').hide(); $('#chats_disclosure').hide(); // declare let ethereum: any; // 1. Define constants // const projectId = 'e7f3d5f95dacb65d61e3e69e66285f2a' // const metadata = { // name: 'chat_psc', // } // 2. Create wagmiConfig // const chains = [polygonZkEvm]; // const wagmiConfig = defaultWagmiConfig({ // chains, // projectId, // metadata, // }); // 3. Create modal // const modal = createWeb3Modal({ wagmiConfig, projectId, chains }); // const wallet = new ArweaveWebWallet({ // Initialize the wallet as soon as possible to get instant auto reconnect // name: 'philiaSocial Collective', // logo: 'https://jfbeats.github.io/ArweaveWalletConnector/placeholder.svg' // }); declare global { interface Window { glow: any; } } // function connect() { // if (getAccount().isConnected) { // disconnect(); // } else { // modal.open(); // } // } const btnEl = document.getElementById('btn'); const userEl = document.getElementById('account_connected'); btnEl.innerText = 'Connect'; userEl.innerText = 'Wallet Not Connected'; btnEl.addEventListener('click', () => { if (btnEl.innerText === 'Connect') { connect(); } else { disconnect(); } }); // function to update UI based on connection status function updateUI(isConnected: boolean, address: string) { userEl.innerText = isConnected ? address : 'Wallet Not Connected'; btnEl.innerText = isConnected ? 'Disconnect' : 'Connect'; } async function disconnect() { try { await window.glow.disconnect(); updateUI(false, ""); } catch (error) { console.error('Error disconnecting wallet:', error); } } let wallet; // modify your connect function async function connect() { try { wallet = await window.glow.connect(); if (wallet && wallet.address) { wallet.address updateUI(true, wallet.address); } else { updateUI(false, ""); } } catch (error) { userEl.innerText = 'Please Download Glow Wallet'; const glowInstalled = window.glow != null; if (!glowInstalled) { window.open("https://glow.app", "_blank"); } } } // // modify your connect function // async function connect() { // try { // console.dir(window.glow); // const resp = await window.glow.connect(); // // console.log(resp) // if (resp) { // // wallet.disconnect(); // assume disconnect is a method on wallet // updateUI(true, resp.address); // } else { // // wallet.setUrl('https://arweave.app') // // await wallet.connect(); // updateUI(false, ""); // // assume getAddress is a method on wallet // } // } catch (error) { // userEl.innerText = 'Please Download Glow Wallet'; // const glowInstalled = window.glow != null; // if (!glowInstalled) { // window.open("https://glow.app", "_blank"); // } // } // // if (wallet.connected) { // // wallet.disconnect(); // assume disconnect is a method on wallet // // updateUI(false, ""); // // } else { // // wallet.setUrl('https://arweave.app') // // await wallet.connect(); // // updateUI(true, wallet.address); // assume getAddress is a method on wallet // // } // } // btnEl.addEventListener('click', connect); // let connectedAddress = wallet.address; // Listening for account changes // watchAccount(account => { // connectedAddress = account.address ?? ''; // Update the connected address // if (account.isConnected) { // userEl.innerText = connectedAddress; // btnEl.innerText = 'Disconnect'; // } else { // userEl.innerText = 'Wallet not connected'; // Set placeholder text when not connected // btnEl.innerText = 'Connect'; // } // }); // use(Web3ClientPlugin); const db = new Polybase({ defaultNamespace: "data_space", signer: (data) => { // Enter your condition to skip the signing process. return null; } }); const collectionReference = db.collection("cid"); const decoder = new TextDecoder(); let uploadedFiles = []; $("#algo_button_box").hide(); // $("#container_algorand").hide(); //===================================================================== // BUTTONS LAYER //===================================================================== $( "#love_matchings" ).on('click', function() { $("#love_matchings").addClass("animated"); // Open the new window after the transition or animation has completed setTimeout(function() { window.open("https://love.philiasocial.repl.co/", '_blank'); }, 500); }); $( "#infinity_nomads" ).on('click', function() { $("#infinity_nomads").addClass("animated"); // Open the new window after the transition or animation has completed setTimeout(function() { window.open("https://infinity.farfallasocial.repl.co/", '_blank'); }, 500); }); $( "#info_riddles" ).on('click', function() { $("#info_riddles").addClass("animated"); // Open the new window after the transition or animation has completed setTimeout(function() { //info_riddles modal $("#modal_riddle_info").toggle(); $('#modal_riddle_info').css('display', 'block'); $('#ok_closing').on('click', function(){ $('#algo_button_box').scrollTop(0); $('#creative_modal').scrollTop(0); $('#modal_riddle_info').scrollTop(0); $('#modal_riddle_info').hide(); $('#creative_modal').hide(); $('#blurred_backdrop').hide(); }); //info_riddles modal }, 400); }); $( "#info_pop" ).on('click', function() { if($('#info_box').length == 0){ $('#anchor_info_pop').append(` <div id='info_box'> <div id='title_steps'>Guidance</div> <div class="line-break0"></div> <div class='first_step'>If you require a translator, we enjoy using this <a href="https://www.deepl.com/translator" target="_blank">Deep Learning model</a>.</div> <div class="line-break0"></div> <div class='first_step'>If you require a place to store your notes securely and privaely, we enjoy using this <a href="https://www.protectedtext.com/" target="_blank">Protected Text</a>.</div> <div class="line-break0"></div> <div class='first_step'>For mobile notifications, we use the decentralized messenger, <a href="https://elixxir.io/" target="_blank">xx messenger</a>. In our personal workflows, in practice, we first send the message within the philiSocial Chat, and then sent a @ or ! within xx messenger to notify our contacts.</div> <div class="line-break0"></div> <div class='first_step'>PhiliaSocial Chat uses Aes256Gcm; for further reading visit this <a href="https://crates.io/crates/aes-gcm" target="_blank">Rust crate.</a></div> <div class="line-break0"></div> <div class='first_step'>The locally encrypted messages and files are uploaded to the <a href="https://www.arweave.org/" target="_blank">Arweave network</a> using the <a href="https://irys.xyz/" target="_blank">Irys Network</a>. The CIDs of your data are then stored on <a href="https://polybase.xyz/" target="_blank">Polybase</a>, within Polybase, the CIDs are stored under a single "collection"; this adds a "lost in the crowd" complexity to the message route. Please be mindful that the encrypted files are not guaranteed to be available indefinitely due the beta nature of PhiliaSocial Chat.</div> <div class="line-break0"></div> <div class='first_step'>On another note, use <a href="https://giphy.com/" target="_blank">Giphy</a> or <a href="https://tenor.com/" target="_blank">Tenor</a> to insert GIF-links into your Chat-space.</div> <div class="line-break0"></div> <div class='first_step'>Contact us: connect at philia dot social</div> </div> `); }; }); $( "#anchor_info_pop" ).on('click', function() { if($('#info_box').length){ $('#info_box').remove(); } }); $( "#note_pad" ).on('click', function() { $("#note_pad").addClass("animated"); // Open the new window after the transition or animation has completed setTimeout(function() { window.open(`https://cryptgeon.org/`, '_blank'); }, 500); }); $("#show_hide_password").on('click',function() { const check_val = $('.fa-eye').length; switch(check_val){ case 1: $(".survey-options").attr("type", "text"); $("#fa_eye") .removeClass("fa-solid fa-eye") .addClass("fa-solid fa-eye-slash"); break; default: $(".survey-options").attr("type", "password"); $("#fa_eye") .removeClass("fa-solid fa-eye-slash") .addClass("fa-solid fa-eye"); break; } } ); init().then(() => { setTimeout(() => { $(".container_intro").fadeOut(2000); $("#algo_button_box").show(); }, 2000); async function public_key_step(){ $('#ft_expanded_2').append(` <div id="spacing_second" class="line-break0"></div> <div id="second_orig" class="peer_orig_inputs">Click the Copy button above to copy the complete Chat-Credentials below, then navigate to Cryptgeon and create a note with them; share the generated link with your partner(s).</div> <div id="survey_pub_key2" class="survey_options_algo2"> <input id="association_algo_password" type="password" name="survey_options_name" class="survey-options"/> </div> `) }; $('#gif_spiral').on('click', function() { document.getElementById('blurred_backdrop').style.display = 'block'; document.getElementById('creative_modal').style.display = 'block'; }); $('#creative_modal_close').on('click', function() { // const account = algosdk.generateAccount(); // const mnemonic = algosdk.secretKeyToMnemonic(account.sk); // $('#mnemonic').text(mnemonic); document.getElementById('blurred_backdrop').style.display = 'none'; document.getElementById('creative_modal').style.display = 'none'; }); function toggleFullScreen() { const elem = document.getElementById('image_riddle'); if (!document.fullscreenElement) { elem.requestFullscreen().catch(err => { alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`); }); } else { document.exitFullscreen(); } } // Initialize the provider // const provider = new ethers.JsonRpcProvider('https://zkevm-rpc.com'); const recipientAddress = "0xB93D4A897B500F3D51b631A0Fd53d842C7aeDF57"; // The amount of ETH to send (0.05 ETH, for example) // const amount = ethers.parseEther("0.00065"); function isValidUrl(string) { try { new URL(string); return true; } catch (_) { return false; } } function showModal(text): void { const modal: HTMLElement | null = document.getElementById('modal_seed_message'); if (modal) { modal.style.display = 'block'; const integratorElement = document.createElement('p'); if (isValidUrl(text)) { const divElement = document.createElement('div'); divElement.id = "gif_spiral2"; integratorElement.appendChild(divElement); modal.appendChild(integratorElement); integratorElement.onclick = () => { window.open(`${text}`, '_blank'); }; } else { integratorElement.textContent = text; modal.appendChild(integratorElement); } modal.onclick = () => { modal.style.display = 'none'; // Hide the modal after 4 seconds modal.removeChild(integratorElement); // Remove the paragraph element from the modal modal.onclick = null; // Remove the click event listener from the modal }; } } // let signer = null; // let provider; const LAMPORTS_PER_SOL = 1_000_000_000; async function fetchTokenPrice(): Promise<number> { const response = await fetch('https://usdethprice-philiasocial.replit.app/token_price'); if (!response.ok) { throw new Error(`Network response was not ok: ${response.statusText}`); } const res = await response.json(); return res.token_price; } // async function sending_post(combinedString: string) { // try { // const userPublicKey = new PublicKey(wallet.address); // // let tx = new Transaction(); // // const connection = new Connection('http://rpc.solscan.com'); // // console.log(connection) // // const { blockhash } = await connection.getLatestBlockhash(); // // tx.recentBlockhash = blockhash; // // tx.feePayer = userPublicKey; // // // Add Memo Instruction // // tx.add( // // new TransactionInstruction({ // // keys: [{ pubkey: userPublicKey, isSigner: true, isWritable: true }], // // data: Buffer.from(combinedString, "utf-8"), // // programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), // // }) // // ); // // Determine the amount to transfer // const tokenPrice = await fetchTokenPrice(); // const amountInSol = Math.ceil((1 / tokenPrice) * 1000) / 1000; // const amountInLamports = amountInSol * LAMPORTS_PER_SOL; // // Add Transfer Instruction // const transaction = new Transaction().add( SystemProgram.transfer({ // fromPubkey: userPublicKey,toPubkey: new PublicKey("7nbet512GtFRGiPrrS7Ji1BXjdfAeFYQWG7tNqBatvW6"), // lamports: amountInLamports}),); // // Convert transaction to base-64 encoding // // const transactionBase64 = tx.serialize().toString('base64'); // // Sign and Send Transaction using Glow // const { signature } = await window.glow.signAndSendTransaction({ // transactionBase64: transaction, // network: "mainnet", // waitForConfirmation: true // }); // // Return the transaction signature // console.log(signature); // } catch (error) { // console.error('Failed to send transaction:', error); // } // } async function getLatestBlockhash() { try { const response = await fetch('https://solana-blockdata-philiasocial.replit.app/getLatestBlockhash'); if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); } const blockhash = await response.text(); // assuming the blockhash is returned as plain text return blockhash; } catch (error) { console.error('Failed to fetch blockhash:', error); throw error; // re-throw the error so it can be handled by the calling code } } async function sending_post(combinedString: string) { try { const userPublicKey = new PublicKey(wallet.address); const blockhash = await getLatestBlockhash(); console.log(blockhash) // Determine the amount to transfer const tokenPrice = await fetchTokenPrice(); const amountInSol = 1 / tokenPrice; const amountInLamports = Math.floor(amountInSol * LAMPORTS_PER_SOL); console.log(amountInLamports) // Add Transfer Instruction // Add Transfer Instruction const transferInstruction = SystemProgram.transfer({ fromPubkey: userPublicKey, toPubkey: new PublicKey("7nbet512GtFRGiPrrS7Ji1BXjdfAeFYQWG7tNqBatvW6"), lamports: amountInLamports, }); console.log(combinedString) // Add Memo Instruction const memoInstruction = new TransactionInstruction({ keys: [{ pubkey: userPublicKey, isSigner: true, isWritable: true }], data: Buffer.from(combinedString, "utf-8"), programId: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), }); // Combine the transfer and memo instructions into an array const instructions = [ transferInstruction, memoInstruction, ]; // create v0 compatible message const messageV0 = new TransactionMessage({ payerKey: userPublicKey, recentBlockhash: blockhash, instructions, }).compileToV0Message(); const serializedTransactionV0 = new VersionedTransaction(messageV0).serialize(); // Convert the serialized transaction to a base64 string const transactionBase64 = Buffer.from(serializedTransactionV0).toString('base64'); // Sign and Send Transaction using Glow const { signature } = await window.glow.signAndSendTransaction({ transactionBase64: transactionBase64, network: "mainnet", // Note: Changed from "mainnet" to "devnet" as per your example waitForConfirmation: true }); // Return the transaction signature console.log(signature); if(signature) { await sendWords(signature, wallet.address); // showModal(); } else { console.error('Transaction hash is not available'); } } catch (error) { console.error('Failed to send transaction:', error); } } // async function sending_post(combinedString: string) { // if (!wallet.address) { // console.error('No account is connected'); // return; // } // try { // const response = await fetch('https://usdethprice-philiasocial.replit.app/token_price'); // if (!response.ok) { // throw new Error('Network response was not ok ' + response.statusText); // } // const res = await response.json(); // // console.log(res) // let tkn_price = res.token_price; // // console.log(tkn_price) // // console.log(Math.ceil((1/ tkn_price) * 10) / 10) // const amountInSol = Math.ceil((1/ tkn_price) * 10) / 10; // const amountInLamports = amountInSol * 1_000_000_000; // // Create a function to add a memo to your transaction // // Step 4: Construct a transaction to transfer the calculated amount of lamports // const transaction = new Transaction(); // const recipient = new PublicKey('7nbet512GtFRGiPrrS7Ji1BXjdfAeFYQWG7tNqBatvW6'); // Replace with the recipient's public key // const sender = new PublicKey(wallet.address); // Replace with the recipient's public key // transaction.add( // SystemProgram.transfer({ // fromPubkey: sender, // Assuming glow.publicKey is your wallet's public key // toPubkey: recipient, // lamports: amountInLamports, // }) // ); // const memoProgramId = new PublicKey('Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo'); // const memoData = Buffer.from('Your memo text here', 'utf-8'); // const memoInstruction = { // keys: [], // programId: memoProgramId, // data: memoData, // }; // transaction.add(memoInstruction); // // Step 5: Serialize the transaction to a base-64 encoded string // const transactionBase64 = btoa(String.fromCharCode(...new Uint8Array(transaction.serialize()))); // // Step 6: Send the transaction using the signAndSendTransaction method of the Glow wallet // await window.glow.signAndSendTransaction({ // transactionBase64, // network: "devnet", // waitForConfirmation: true, // }); // } catch (error) { // // console.error('Failed to send txn:', error); // } // // try { // // const response = await fetch('https://usdethprice-philiasocial.replit.app/eth_price'); // // if (!response.ok) { // // throw new Error('Network response was not ok ' + response.statusText); // // } // // const res = await response.json(); // // // console.log(res) // // let sevenUsdInEth = res.sevenUsdEth; // // sevenUsdInEth = Math.round(1/sevenUsdInEth * 1e18) / 1e18; // // const amount = ethers.parseEther(`${sevenUsdInEth}`); // // const data = ethers.hexlify(ethers.toUtf8Bytes(`${data_string.toString()}`)); // // provider = new ethers.BrowserProvider(window.ethereum as any); // // signer = await provider.getSigner(connectedAddress); // // const tx = await signer.sendTransaction({ // // to: recipientAddress, // // value: amount, // // data: data // include the data field in your transaction object // // }); // // // console.log('Transaction hash:', tx.hash); // // // showModal(tx.hash); // // if(tx.hash) { // // await sendWords(tx.hash, connectedAddress); // // // showModal(); // // } else { // // console.error('Transaction hash is not available'); // // } // // } catch (error) { // // console.error('Failed to send txn:', error); // // } // } async function sendWords(txnhash: string, connectedaddr: string): Promise<void> { const serverUrl = 'https://checking-philiasocial.replit.app/getTransaction'; console.log(txnhash) console.log(connectedaddr) console.log(JSON.stringify({ txnhash: txnhash, connectedaddress: connectedaddr })) try { const response = await fetch(serverUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ txnhash: txnhash, connectedaddress: connectedaddr }) }); // Assume `response` is the Response object you get from calling fetch let rendering = await response.text() console.log(rendering) showModal(rendering) // Output: the link or error message from the server } catch (error) { console.error('Error:', error.message); } } // jQuery function to handle the click event // let gaps = []; // Define the click event handler function async function handleClick() { let combinedString = ''; for (let i = 1; i <= 7; i++) { const gapText = $(`#gap${i}`).text().trim(); combinedString += gapText + ' '; // Add a space after each word } combinedString = combinedString.trim(); // Remove trailing space combinedString = 'chat.philia.social: ' + combinedString; // Prepend label // const text: string = $("#zkevm_message").text(); // console.log(combinedString); sending_post(combinedString); } // Bind the click event handler $("#generate_algo").on("click", handleClick); $("#image_riddle").on("click", function(){ toggleFullScreen(); }); // zkevm setup // Function to add the zkEVM network async function addZkEVMNetwork() { // if (window.ethereum) { // try { // // Parameters for the Polygon zkEVM mainnet // const params = { // chainId: '0x44D', // Chain ID for Polygon zkEVM, converted from 1101 to hexadecimal // chainName: 'Polygon zkEVM', // nativeCurrency: { name: 'Ethereum', symbol: 'ETH', decimals: 18 }, // rpcUrls: ['https://zkevm-rpc.com'], // RPC URL // blockExplorerUrls: ['https://zkevm.polygonscan.com'] // Block explorer URL // }; // // Request to add the network // await ethereum.request({ // method: 'wallet_addEthereumChain', // params: [params], // }); // } catch (error) { // console.error(error); // alert('Failed to add network or token'); // } // } else { // alert('Ethereum provider not found'); // } } // Set up the event listener document.getElementById('zkevm_setup').addEventListener('click', addZkEVMNetwork); // zkevm setup $("#input_label_button_pub_key").on('click',function() { // $("#input_label_button_farfalla_key").hide(); // $("#input_label_button_contact_key").hide(); // $("#original_space").hide(); $("#first_task").hide(); $("#third_task").hide(); let condition_ft = $( "#input_label_button_pub_key" ).html() === `Create New Credentials`; const expandedContent = document.getElementById('ft_expanded_2') as HTMLDivElement; if(condition_ft == true){ $( "#input_label_button_pub_key" ).text(`Return Home`); if (expandedContent.style.display === 'block') { expandedContent.style.display = 'none'; } else { expandedContent.style.display = 'block'; if( $("#association_algo_password").length == 0 ){ public_key_step().then(() => { // const new_public = generate_public_key(); // const new_chat = new_chat_id(); const new_chat = encode_base64(uuid_generate()); const new_public = password().replace(/=/g, ''); // console.log([new_chat.length, new_public.length]) const joined_credentials = new_chat + new_public // console.log(joined_credentials) $("#association_algo_password").val(`${joined_credentials}`); }); }; }; } else { $( "#input_label_button_pub_key" ).html(`Create New Credentials`); expandedContent.style.display = 'none'; // $("#input_label_button_farfalla_key").show(); // $("#input_label_button_contact_key").show(); // $("#original_space").show(); $("#first_task").show(); $("#third_task").show(); $("#association_algo_password").remove(); $("#association_algo_password0").remove(); $(".survey_options_algo2").remove(); $("#second_orig").remove(); $("#spacing_second").remove(); $("#soft_encrypted_credential").remove(); }; }); async function initial_text_area_view(){ if($("#association_algo_password4").length == 0){ $("#wrapper_username").append(` <div class="inputs_labels">Add any optional metadata:</div> <div id class="line-break0"></div> <div class="survey_options_algo"> <input id="association_algo_password4" type="text" name="survey_options_name4" class="survey-options" placeholder="Ex: 01 Mikasa A."/> </div> <div class="messages_labels"> <div>Safe Qty.</div> <div>Risky Qty.</div> </div> <div id="messages_count"></div> <div class="messages_labels"> <div>0</div> <div>Messages</div> <div>500</div> </div> `); }; // try{ // await loop_algorand(global_chat_space_key,chat_space_private); } $(document).ready(function () { // Event listener for 'keydown' on input element with ID 'association_algo_password2' $('#association_algo_password2').on('keydown', async function (event) { if (event.key === 'Enter') { event.preventDefault(); // Prevent the default action of the Enter key const credentialsArray = $("#association_algo_password2").val().toString().trim().split(','); for (const credentials of credentialsArray) { await processSingleCredential(credentials.trim()); } } }); let addedChatIds = new Set(); // Event listener for 'click' on element with ID 'input_label_button_farfalla_key' $("#input_label_button_farfalla_key").on('click', async function () { const credentialsArray = $("#association_algo_password2").val().toString().trim().split(','); for (const credentials of credentialsArray) { await processSingleCredential(credentials.trim()); } }); // $("#wallet_connected_chat").on('click', function () { // // window.open(`https://explorer.testnet.polybase.xyz/collections/data_space%2Fcid`, '_blank'); // $("#container_algorand").show(); // }); const htmlTemplate = ` <div class="line-break1"></div> <div class="line-break0"></div> <!-- <div class="wallet_connected_wrapper"> --> <!-- <div id="wallet_connected_chat"></div> --> <div class="line-break1"></div> <div class="line-break0"></div> <div id="wrapper_picker"> <div id="picker"></div> <div id="wrapper_username"></div> </div> <div class="line-break1"></div> <div id="fs_button_loader_wrapper1"> <div id="wrapper_message_tools1"> <div id="blur_mess" class="boxes"> <i class="chat_space fa-solid fa-mask"></i> </div> <div id="add_file" class="boxes"> <i class="chat_space fa-solid fa-plus"> <input type="file" id="file-input" accept="audio/mpeg, audio/x-m4a, audio/wav, audio/flac, video/mp4, video/quicktime, image/png, image/jpeg, text/plain, application/pdf" style="display: none"> </i> </div> <div id="refresh" class="boxes"> <i class="chat_space fa-solid fa-at"></i> </div> </div> </div> <div class="line-break0"></div> <div id="wallet_connected_text_id"></div> <!-- <div class="line-break1"></div> --> <div id="wrapper_glass"></div> <div id="in_out_messages"> <div class="text_area_data"></div> <div id="text_area_landing"></div> </div> <div class="line-break0"></div> <div id="fs_button_loader_wrapper2"> <div id="wrapper_message_tools2"> <div id="latest_mess" class="boxes"> <i class="chat_space fa-solid fa-camera-retro"></i> </div> <div id="voice_recording" class="boxes"> <i class="chat_space fa-solid fa-microphone"></i> </div> <div id="stop_recording" class="boxes"> <div class="chat_space" id="stop_message">Recording/Stop...</div> </div> <div id="headset" class="boxes"> <i class="chat_space fa-solid fa-headset"></i> </div> <div id="lock_mess" class="boxes"> <i class="chat_space fa-solid fa-paper-plane"></i> </div> </div> </div> <div id="anchor_file_names"></div> <!-- <textarea id="messages" name="message" placeholder="Message"></textarea> --> <div id="messages" contenteditable="true"></div> <div class="line-break1"></div> `; let global_chat_space_key; async function processSingleCredential(credentials: string) { // const assoc_pass2 = $("#association_algo_password2").val().toString().length; if (credentials.length == 91) { // $("#input_label_button_pub_key").hide(); $("#input_label_button_contact_key").hide(); // const credentials = $("#association_algo_password2").val().toString().trim(); const split_credentials_chatId = credentials.substring(0, 48); const split_credentials_private = credentials.substring(48, 91); // let global_chat_space_key = split_credentials_chatId; if (credentials.length == 91 && split_credentials_chatId.length == 48 && split_credentials_private.length == 43) { $('#overlay_algo_gate').show(); $('#algo_gate').show(); $('#chats_title').show(); $('#chats_disclosure').show(); // $("#container_algorand").show(); // chat_space_id = split_credentials_chatId; chat_space_private = split_credentials_private; if (!addedChatIds.has(split_credentials_chatId)) { // Create a new HTML element with a unique id based on split_credentials_chatId const newElement = $(`<div id="wallet_connected_chat_${split_credentials_chatId}"></div>`); // Add a class to the new element newElement.addClass('wallet_connected_chat'); // Append the new element to the DOM, for example, to the body element $('#algo_gate').append(newElement); // Append a divider element to create space $('#algo_gate').append('<div class="line-break1"></div>'); // Update the content of the new element $(`#wallet_connected_chat_${split_credentials_chatId}`).html(`${credentials}`); // Set up a click event listener on the new element $(`#wallet_connected_chat_${split_credentials_chatId}`).on('click', async function() { const credentials2 = $(`#wallet_connected_chat_${split_credentials_chatId}`).text(); const split_credentials_chatId2 = credentials2.substring(0, 48); const split_credentials_private2 = credentials2.substring(48, 91); global_chat_space_key = split_credentials_chatId2; chat_space_private = split_credentials_private2; setTimeout(async function() { const container = $("<div id='container_algorand'></div>") .html(htmlTemplate) .insertAfter('#algo_gate') .show(); // FUNCTIONS FOR THE CHAT SPACE $( "#blur_mess" ).on('click', function() { if($( "#glass" ).length){ $( "#glass" ).remove(); } else { $( "#wrapper_glass" ).append(` <div id="glass"></div> `); } }); var colorPicker = iro.ColorPicker("#picker", { width: 120, color: "#6842ff", borderWidth: 5, borderColor: "#ffffff", layout: [ { component: iro.ui.Wheel, options: {} }, ] }); const main_message = $( "#messages" ); colorPicker.on('color:change', function(color) { main_message.css('color',`${color.hexString}`); }); const uploadDiv = document.getElementById("add_file"); const input = document.getElementById("file-input") as HTMLInputElement; input.addEventListener("change", handleUpload); uploadDiv.addEventListener("click", () => input.click()); async function handleUpload() { const file = input.files[0]; const allowedTypes = [ "audio/mpeg", "audio/x-m4a", "audio/wav", "audio/flac", "audio/webm;codecs=opus", "audio/mp3", "video/mp4", "video/quicktime", "image/png", "image/jpeg", "text/plain", "application/pdf", "image/gif", ]; try { if (file.size > 60 * 1024 * 1024) { // console.log("File size is too large. Maximum file size is 100MB."); } else if (!allowedTypes.includes(file.type)) { } else { $( "#anchor_file_names" ).append(` <div class="file_name"> ${file.name} <div class="line-break0"></div> </div> `); await encryptUploadedFile("", file, file.type); }; } catch (error) { // console.log(error); }; }; $('#anchor_file_names').on('click touchend', function(event) { if ($(event.target).is('.file_name')) { let index = $(event.target).index(); $(event.target).remove(); uploadedFiles.splice(index, 1); } }); let counting_separator = 1; async function unlock_button(links){ const lineBreak0 = $('<div>', {class: 'line-break0'}); const lineBreak1 = $('<div>', {class: 'line-break0'}); const separator = $('<div>', {class: 'separator'}); const counter = $('<div>', {class: 'separator_counter', id:`separator_counter_${links}`, text: `${counting_separator++}`}); let mess_elem: JQuery<HTMLElement>; let unlockElem: JQuery<HTMLElement>; const svgButton = $(` <i class="fa-solid fa-user-lock"></i> `); mess_elem = $('<div>', {class: 'mess_elem', id: `${links}_anchor`}) unlockElem = $('<div>', {class: 'chat_space unlockElem', id: `${links}`}) .append(svgButton); $( ".text_area_data" ) .append(lineBreak0) .append(mess_elem).append(unlockElem) .append(lineBreak1) .append(counter).append(separator) } $('#messages').on('click', async function(){ try{ // await loop_algorand(); const elements = document.querySelectorAll('.separator'); const lastElement = elements[elements.length - 1]; lastElement.scrollIntoView(); } catch(error) { // console.log(error) } }); $("#voice_recording").on('click', async () => { mediaRecorder = new Recorder(); mediaRecorder.start(); $('#voice_recording').hide(); $('#stop_recording').show(); }); $("#stop_recording").on('click', async () => { $('#voice_recording').show(); $('#stop_recording').hide(); mediaRecorder.stop() const blob = mediaRecorder.getWAVBlob(); const fileSize = blob.size / (1024 * 1024); // Size in MBs if (fileSize > 30) { $("#anchor_file_names").append(` <div class="file_name"> <div id="chat_space">Max audio duration reached.</div> <div class="line-break0"></div> </div> `); setTimeout(function() { $("#chat_space").remove(); }, 3000); return; } // Create a new File object from the Blob with a unique filename const file = new File([blob], `${uuid_generate()}.wav`); // Display the filename in the UI and encrypt the uploaded file $("#anchor_file_names").append(` <div class="file_name"> ${file.name} <div class="line-break0"></div> </div> `); await encryptUploadedFile("", file, `audio/wav`); mediaRecorder.destroy().then(function () { mediaRecorder = null; }); }); $('#headset').on('click', async function () { const newUUID = uuid_generate(); // https://c2c.mirotalk.com/join?room=${newUUID}&name=li const randomName = uniqueNamesGenerator({ dictionaries: [adjectives, colors, animals] }); const videoChatUrl = `https://c2c.mirotalk.com/join?room=${newUUID}&name=${randomName}`; window.open(videoChatUrl, '_blank'); }); $('#lock_mess').on('click', async function(){ try { const encryption = new Encryption(chat_space_private); // const chat_id = await get_chat_space_key(); if (main_message.html().length > 0){ const timestamp_box = $( "#association_algo_password4" ).val().toString(); // Get the HTML content of the message and replace <br> tags with !@#$ let replaced_message = main_message.html().toString().replace(/<br>/g, "!@##@!"); const complete_message = `${timestamp_box}: ${replaced_message}`; // Default MIME type let mimeType = 'text/plain'; const blob = new Blob([complete_message], {type: mimeType}); const file = new File([blob], `${uuid_generate()}.txt`); await encryptUploadedFile(`${colorPicker.color.hexString}`, file, mimeType); }; if ( uploadedFiles.length > 0) { $("#wrapper_message_tools1").hide(); $("#wrapper_message_tools2").hide(); $('#fs_button_loader_wrapper1').append(` <div class="chat_space" id="a_message">Working...</div> `); $("#fs_button_loader_wrapper1").show(); // $("#fs_button_loader_wrapper2").show(); storeFiles(uploadedFiles).then( async (cid_res) => { const epochTimestamp = Math.floor(new Date().getTime() / 1000); // const epochTimestamp_encoded = encode_base64(`${epochTimestamp}`).replace(/=+$/, ''); const message_id = password().replace(/=+$/, ''); const uint8Array_cid = new TextEncoder().encode(cid_res); const cid_encrypted = await encryption.encrypt(uint8Array_cid); const cid_encrypted_enc = vec_to_base64( cid_encrypted).replace(/=+$/, ''); async function createRecord () { await collectionReference.create([message_id, global_chat_space_key, epochTimestamp ,cid_encrypted_enc]); } createRecord().then(() => { $("#wrapper_message_tools1").show(); $("#wrapper_message_tools2").show(); uploadedFiles = []; main_message.text(``); $('.file_name').text(``) $("#a_message").remove(); }); }); }; } catch (error) { // console.log(error) }; }); $('#refresh').on('click', function(){ $("#refresh").addClass("animated"); // Open the new window after the transition or animation has completed setTimeout(function() { $('#container_algorand').remove(); $("#association_algo_password2").val("") }, 500); }); //Web-worker let ipfs_links = []; async function composition_notes(links) { try { // Wait for all the outer promises to resolve await Promise.all( links.map(async (note) => { // Create an array of promises for the inner loop const innerPromises = note.map((x) => { const arweave_obj_id = uuid_generate(); fetch_data_links.push(x); fetch_data_links_ids.push(arweave_obj_id); // Chain the unlock_button() promise without using async/await within the map return unlock_button(arweave_obj_id); }); // Wait for all the inner promises to resolve await Promise.all(innerPromises); }) ); } catch (error) { // Handle the error } } const processArrayNotes = async (notes) => { cache.clear(); // console.log("init") $("#wrapper_message_tools1").hide(); $("#wrapper_message_tools2").hide(); if ($('#a_message').length === 0) { $('#fs_button_loader_wrapper1').append(` <div class="chat_space" id="a_message">Working...</div> `); } try { interface EncryptedFileResult { index: number; result: string; } const promises = notes.map((note, index) => // console.log(note) fetchEncryptedFileMemoized(note, index) ); const results = await Promise.all<EncryptedFileResult>(promises); // console.log(results) results.sort((a, b) => a.index - b.index); ipfs_links = results.map((res) => res.result); $("#wrapper_message_tools1").show(); $("#wrapper_message_tools2").show(); $("#a_message").remove(); composition_notes(ipfs_links); const elements = document.querySelectorAll('.separator'); const lastElement = elements[elements.length - 1]; lastElement.scrollIntoView(); } catch (error) { } finally { $("#fs_button_loader_wrapper1").show(); } }; const cache = new Map(); async function fetchEncryptedFileMemoized(note, index) { // const cacheKey = `encryptedFile_${note.id}`; const cacheKey = note.id; if (cache.has(cacheKey)) { return { result: cache.get(cacheKey), index }; } const result = await fetchEncryptedFile(note); cache.set(cacheKey, result); return { result, index }; } async function fetchEncryptedFile(cid: string): Promise<any> { try { const response = await fetch(`https://arweave.net/${cid}`); const data = await response.json(); // console.log(data); return data; } catch (error) { console.error(error); } } // Send to Arweave async function storeFiles(files) { try{ const response = await fetch('https://arweavephiliasocial.replit.app', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ files }) }); const data = await response.json(); // console.log(data.cid) return data.cid; }catch(error){ // console.log(error) } }; // let global_chat_space_key:string; let fetch_data_links = []; let fetch_data_links_ids = []; function fetchData_ipfs(link) { let index = fetch_data_links_ids.indexOf(link); // If the id is not found in the array, return null if(index === -1) return null; // Otherwise, return the corresponding element from the array_link array return fetch_data_links[index]; }; $( ".text_area_data" ).on('click', (event) => { // let separator_counter = []; const target = $(event.target); const unlockElem = target.closest('.unlockElem'); if (!unlockElem.length) return; const id = unlockElem.attr('id'); const separator_count_text = $(`#separator_counter_${id}`).text(); $(`#separator_counter_${id}`).text(`Decrypting...`); const ipfs_data = fetchData_ipfs(id); setTimeout(() => { get_ipfs_data(id, ipfs_data, separator_count_text); }, 50); }); async function listRecordsWithFilter (chat_id: string) { const records = await collectionReference .where("name", "==", `${chat_id}`) .sort("time","asc") .limit(10000) .get(); return records } let mess_count_var_loop = 0; let previous_mess_loop = 0; async function get_latest_note(global_chat_space_key,chat_space_private){ // console.log(previous_mess_loop) collectionReference .where("name", "==", `${global_chat_space_key}`) .sort("time","asc") .limit(10000) .onSnapshot( async (newDoc) => { try{ await loop_algorand(global_chat_space_key,chat_space_private); const elements = document.querySelectorAll('.separator'); const lastElement = elements[elements.length - 1]; lastElement.scrollIntoView(); } catch(error) { // console.log(error) } }, (err) => { // Optional error handler } ); } async function loop_algorand(global_chat_space_key,chat_space_private){ let array_notes = []; const encryption = new Encryption(chat_space_private); // const chat_id = await get_chat_space_key(); listRecordsWithFilter(global_chat_space_key).then((records)=>{ records.data.map(x =>{ // console.log(x.data.port) const message_algo_main_sanitized = sanitize_base64(x.data.port); encryption.decrypt(message_algo_main_sanitized) .then(decrypted_algo_main => { const decrypted_algo_main_decoded = decoder.decode(decrypted_algo_main); array_notes.push(decrypted_algo_main_decoded) }); }); }).then(async () => { // try{ // // const set_array_notes = array_notes.reverse(); const set_array_notes = array_notes; const set_array_notes_len = set_array_notes.length; if (previous_mess_loop === 0) { previous_mess_loop = array_notes.length; processArrayNotes(array_notes) }; if (set_array_notes_len > previous_mess_loop) { mess_count_var_loop = set_array_notes_len - previous_mess_loop; const latestMessages = set_array_notes.slice(-mess_count_var_loop); processArrayNotes(latestMessages) previous_mess_loop = set_array_notes_len; }; // } catch(error){ // console.error(error); // }; }); }; const reader = new FileReader(); async function get_ipfs_data(id, ipfs_data, separator_count_text: string) { try{ $(`#${id}`).remove(); const encryption = new Encryption(chat_space_private); const decrypted_hex = await encryption.decrypt( base64_to_vec(ipfs_data.fh)); const decrypted_label = await encryption.decrypt(base64_to_vec(ipfs_data.fl)); const decrypted_hex_decoded = decoder.decode(decrypted_hex); const decrypted_label_decoded = decoder.decode(decrypted_label); const decrypted_data = await encryption.decrypt(base64_to_vec(ipfs_data.fd)); reader.readAsDataURL(new Blob([decrypted_data])); reader.onloadend = () => { try{ const formatMIMETypes = { "audio/mpeg": "audio/mpeg", "audio/mp3": "audio/mp3", "audio/x-m4a": "audio/x-m4a", "audio/wav": "audio/wav", "audio/flac": "audio/flac", "audio/webm;codecs=opus": "audio/webm;codecs=opus", "video/mp4": "video/mp4", "video/quicktime": "video/quicktime", "image/png": "image/png", "image/jpeg": "image/jpeg", "text/plain": "text/plain", "application/pdf": "application/pdf", }; const format = decrypted_label_decoded; const mimeType = formatMIMETypes[format]; if (mimeType.startsWith("audio/")) { const audioBlob = new Blob([decrypted_data], {type: mimeType}); const audioUrl = URL.createObjectURL(audioBlob); $.when($(`#${id}_anchor`).append( $('<audio>', {src: audioUrl, class: "rendered_audio", style: "--plyr-audio-controls-background: #eee;"}) )).done(function(){ $(`#separator_counter_${id}`).text(separator_count_text); Plyr.setup(`.rendered_audio`, { controls: ['play', 'progress', 'current-time', 'mute', 'settings'], autoplay: false, displayDuration: true }); }); } else if (mimeType.startsWith("video/")) { const videoBlob = new Blob([decrypted_data], {type: mimeType}); const videoUrl = URL.createObjectURL(videoBlob); // const set_video_id = `${id}_video`; $.when($(`#${id}_anchor`).append( $('<video>', {src: videoUrl,class: "rendered_vid"}) )).done(function(){ $(`#separator_counter_${id}`).text(separator_count_text); Plyr.setup('.rendered_vid', { controls: ['play', 'progress', 'current-time', 'mute', 'settings', 'fullscreen'], autoplay: false, }); }); } else if (mimeType.startsWith("image/")) { $.when($(`#${id}_anchor`).append( $('<img>', {src: reader.result as string, class: "rendered_img"}) )).done(function(){ $(`#separator_counter_${id}`).text(separator_count_text); }); } else if (mimeType.startsWith("text/")) { let decrypted_text_decoded = decoder.decode(decrypted_data); // Replace the ID with <br> let replaced_text = decrypted_text_decoded.replace(/!@##@!/g, "<br>"); // Find URLs using regular expression and replace them with anchor tags let urlRegex = /((https?:\/\/)|(www\.))[^<\s]+/g; let linked_text = replaced_text.replace(urlRegex, function(url) { let urlWithProtocol = url.startsWith('http') ? url : 'http://' + url; return `<a href="${urlWithProtocol}" target="_blank">${url}</a>`; }); // Create a new jQuery object with the replaced text as its HTML content let text = $('<div>').html(linked_text); text.css('color', decrypted_hex_decoded); // $(`#${id}_anchor`).append(text); $.when($(`#${id}_anchor`).append(text)).done(function(){ $(`#separator_counter_${id}`).text(separator_count_text); }); } else if (mimeType.startsWith("application/")) { const pdfBlob = new Blob([decrypted_data], {type: 'application/pdf'}); const pdfUrl = URL.createObjectURL(pdfBlob); $.when($(`#${id}_anchor`).append( `<a href="${pdfUrl}" target="_blank"><span class="chat_space fa-solid fa-file-pdf"></span></a>` )).done(function(){ $(`#separator_counter_${id}`).text(separator_count_text); }); }; } catch(error) { // console.log(error) } }; } catch(error) { // console.log(error) } } // FUNCTIONS FOR THE CHAT SPACE await initial_text_area_view(); get_latest_note(global_chat_space_key,chat_space_private); }, 300); // 500 is the delay in milliseconds, adjust as necessary }); // Mark this split_credentials_chatId as added addedChatIds.add(split_credentials_chatId); } try { // await initial_text_area_view(); // get_latest_note(); } catch (error) { } } } } }); // Function to confirm that text has been copied function confirmCopied(): void { $(".fa-copy").remove(); $("#copy_field").html("Copied!"); setTimeout(() => { $("#copy_field").html("Copy"); }, 2000); } // Function to handle the click event on the copy field async function handleCopyFieldClick(): Promise<void> { const isReturnHome = $("#input_label_button_pub_key").html() === "Return Home"; if (isReturnHome) { try { const textToCopy = $("#association_algo_password").val() as string; await navigator.clipboard.writeText(textToCopy); confirmCopied(); } catch (error) { console.error("Failed to copy text: ", error); } } } // Attach the click event listener $(document).ready(() => { $("#copy_field").on("click", handleCopyFieldClick); }); }); let chat_space_private:string; let chat_space_id:string; // encrypting files... class Encryption { // public public_k: string; public private_k: string; // public additional: string; constructor(private_k: string) { // this.public_k = public_k; this.private_k = private_k; // this.additional = additional; } async encrypt(data: Uint8Array) { // return encrypt_file(this.key, data); return encrypt_or_decrypt_files2("encrypt", this.private_k, data); } async decrypt(data: Uint8Array) { return encrypt_or_decrypt_files2("decrypt", this.private_k, data); }; }; async function encryptUploadedFile(coloring:string, file: File, labels: string) { $("#wrapper_message_tools1").hide(); $("#wrapper_message_tools2").hide(); $('#fs_button_loader_wrapper1').append(` <div class="chat_space" id="a_message">Working...</div> `); $("#fs_button_loader_wrapper1").show(); // $("#fs_button_loader_wrapper2").show(); const encryption = new Encryption(chat_space_private); // console.log(chat_space_key); // Read the file as an ArrayBuffer const buffer = await new Response(file).arrayBuffer(); const textEnc = new TextEncoder() const uint8Array_col = textEnc.encode(coloring); const uint8Array_lab = textEnc.encode(labels); // Encrypt the file const encryptedColoring = await encryption.encrypt(uint8Array_col); const encryptedFile = await encryption.encrypt(new Uint8Array(buffer)); // const encryptedFile = await encrypt_file(chat_space_key, new Uint8Array(buffer)); const encryptedLabels = await encryption.encrypt(uint8Array_lab); const colo_enc = vec_to_base64(encryptedColoring); const file_enc = vec_to_base64(encryptedFile); const labels_enc = vec_to_base64(encryptedLabels); // Create the object and the blob const obj = { fh: colo_enc, fl:labels_enc, fd: file_enc } uploadedFiles.push(obj); $("#wrapper_message_tools1").show(); $("#wrapper_message_tools2").show(); $("#a_message").remove(); }; $('#stop_recording').hide(); let mediaRecorder; $('#overlay_algo_gate').on('click', function(){ $('#algo_gate').hide() $('#overlay_algo_gate').hide() $('#chats_title').hide(); $('#chats_disclosure').hide(); }); (window as any).getSuggestions = async function(gapId: string): Promise<void> { const spanElement = document.getElementById(gapId) as HTMLSpanElement; const words = spanElement.textContent?.split(' ') || []; const query = words[words.length - 1]; if (query.length === 0) { clearSuggestions(); return; } try { const response = await fetch(`https://autofillgame-philiasocial.replit.app/get-words?query=${query}`); const suggestions = await response.json(); displaySuggestions(suggestions, words.slice(0, -1).join(' '), gapId); } catch (error) { // Handle error console.error(error); } } function displaySuggestions(suggestions: string[], precedingWords: string, gapId: string): void { try { const listElement = document.querySelector('.suggestions-list'); if (listElement) { listElement.innerHTML = ''; for (const suggestion of suggestions) { const listItem = document.createElement('button'); listItem.textContent = suggestion; listItem.className = 'bubble-button'; // Apply the class to each button listItem.onclick = function() { const spanElement = document.getElementById(gapId) as HTMLSpanElement; spanElement.textContent = `${precedingWords} ${suggestion} `; clearSuggestions(); }; listElement.appendChild(listItem); } } } catch (error) { // Handle error ; } } function clearSuggestions(): void { const listElement = document.querySelector('.suggestions-list') as HTMLUListElement; if (listElement) { listElement.innerHTML = ''; } }