| 6 | "": "/** * NearGram - Global Edition (Final All-in-One)\\\\n * Version: 6 Languages, Premium Header, Integrated Inbox\\\\n * Built by: qelo.near \\\\u{2022} Built on NEAR Protocol\\\\n */\\\\n\\\\nconst accountId = context.accountId;\\\\n\\\\nif (!accountId) {\\\\n return (\\\\n <div\\\\n className=\\\\\\\"alert alert-warning text-center mt-5\\\\\\\"\\\\n style={{\\\\n borderRadius: \\\\\\\"16px\\\\\\\",\\\\n backgroundColor: \\\\\\\"#fffbeb\\\\\\\",\\\\n border: \\\\\\\"1px solid #f59e0b\\\\\\\",\\\\n }}\\\\n >\\\\n Please sign in to use NearGram Global.\\\\n </div>\\\\n );\\\\n}\\\\n\\\\n// 1. Kamus Bahasa Global (6 Mode)\\\\nconst T = {\\\\n en: {\\\\n title: \\\\\\\"NearGram\\\\\\\",\\\\n tagline: \\\\\\\"Global On-Chain Social Messaging\\\\\\\",\\\\n recipientLabel: \\\\\\\"Recipient Address\\\\\\\",\\\\n recipientPlaceholder: \\\\\\\"e.g., qelo.near\\\\\\\",\\\\n messageLabel: \\\\\\\"Message\\\\\\\",\\\\n messagePlaceholder: \\\\\\\"Type your message here...\\\\\\\",\\\\n sendBtn: \\\\\\\"Send Message (Blockchain)\\\\\\\",\\\\n successMsg: \\\\\\\"Message sent successfully!\\\\\\\",\\\\n inboxTitle: \\\\\\\"\\\\u{1f4e5} Your Inbox\\\\\\\",\\\\n from: \\\\\\\"Message from\\\\\\\",\\\\n reply: \\\\\\\"Reply\\\\\\\",\\\\n footer: \\\\\\\"Global Messaging System by qelo.near\\\\\\\",\\\\n },\\\\n id: {\\\\n title: \\\\\\\"NearGram\\\\\\\",\\\\n tagline: \\\\\\\"Kirim Pesan Global Tanpa Batas\\\\\\\",\\\\n recipientLabel: \\\\\\\"Alamat Penerima\\\\\\\",\\\\n recipientPlaceholder: \\\\\\\"contoh: qelo.near\\\\\\\",\\\\n messageLabel: \\\\\\\"Isi Pesan\\\\\\\",\\\\n messagePlaceholder: \\\\\\\"Tulis pesanmu di sini...\\\\\\\",\\\\n sendBtn: \\\\\\\"Kirim Pesan (Blockchain)\\\\\\\",\\\\n successMsg: \\\\\\\"Pesan berhasil terkirim!\\\\\\\",\\\\n inboxTitle: \\\\\\\"\\\\u{1f4e5} Kotak Masuk\\\\\\\",\\\\n from: \\\\\\\"Pesan dari\\\\\\\",\\\\n reply: \\\\\\\"Balas\\\\\\\",\\\\n footer: \\\\\\\"Global Messaging System by qelo.near\\\\\\\",\\\\n },\\\\n es: {\\\\n title: \\\\\\\"NearGram\\\\\\\",\\\\n tagline: \\\\\\\"Mensajer\\\\u{ed}a Social Global On-Chain\\\\\\\",\\\\n recipientLabel: \\\\\\\"Direcci\\\\u{f3}n del Destinatario\\\\\\\",\\\\n recipientPlaceholder: \\\\\\\"ej., qelo.near\\\\\\\",\\\\n messageLabel: \\\\\\\"Mensaje\\\\\\\",\\\\n messagePlaceholder: \\\\\\\"Escribe tu mensaje aqu\\\\u{ed}...\\\\\\\",\\\\n sendBtn: \\\\\\\"Enviar por Blockchain\\\\\\\",\\\\n successMsg: \\\\\\\"\\\\u{a1}Mensaje enviado con \\\\u{e9}xito!\\\\\\\",\\\\n inboxTitle: \\\\\\\"\\\\u{1f4e5} Tu Bandeja de Entrada\\\\\\\",\\\\n from: \\\\\\\"Mensaje de\\\\\\\",\\\\n reply: \\\\\\\"Responder\\\\\\\",\\\\n footer: \\\\\\\"Global Messaging System by qelo.near\\\\\\\",\\\\n },\\\\n fr: {\\\\n title: \\\\\\\"NearGram\\\\\\\",\\\\n tagline: \\\\\\\"Messagerie Sociale Mondiale On-Chain\\\\\\\",\\\\n recipientLabel: \\\\\\\"Adresse du Destinataire\\\\\\\",\\\\n recipientPlaceholder: \\\\\\\"ex., qelo.near\\\\\\\",\\\\n messageLabel: \\\\\\\"Message\\\\\\\",\\\\n messagePlaceholder: \\\\\\\"Tapez votre message ici...\\\\\\\",\\\\n sendBtn: \\\\\\\"Envoyer via Blockchain\\\\\\\",\\\\n successMsg: \\\\\\\"Message envoy\\\\u{e9} avec succ\\\\u{e8}s !\\\\\\\",\\\\n inboxTitle: \\\\\\\"\\\\u{1f4e5} Votre Bo\\\\u{ee}te de R\\\\u{e9}ception\\\\\\\",\\\\n from: \\\\\\\"Message de\\\\\\\",\\\\n reply: \\\\\\\"R\\\\u{e9}pondre\\\\\\\",\\\\n footer: \\\\\\\"Global Messaging System by qelo.near\\\\\\\",\\\\n },\\\\n zh: {\\\\n title: \\\\\\\"NearGram\\\\\\\",\\\\n tagline: \\\\\\\"\\\\u{5168}\\\\u{7403}\\\\u{94fe}\\\\u{4e0a}\\\\u{793e}\\\\u{4ea4}\\\\u{6d88}\\\\u{606f}\\\\\\\",\\\\n recipientLabel: \\\\\\\"\\\\u{6536}\\\\u{4ef6}\\\\u{4eba}\\\\u{5730}\\\\u{5740}\\\\\\\",\\\\n recipientPlaceholder: \\\\\\\"\\\\u{4f8b}\\\\u{5982}: qelo.near\\\\\\\",\\\\n messageLabel: \\\\\\\"\\\\u{4fe1}\\\\u{606f}\\\\\\\",\\\\n messagePlaceholder: \\\\\\\"\\\\u{5728}\\\\u{6b64}\\\\u{8f93}\\\\u{5165}\\\\u{60a8}\\\\u{7684}\\\\u{4fe1}\\\\u{606f}...\\\\\\\",\\\\n sendBtn: \\\\\\\"\\\\u{901a}\\\\u{8fc7}\\\\u{533a}\\\\u{5757}\\\\u{94fe}\\\\u{53d1}\\\\u{9001}\\\\\\\",\\\\n successMsg: \\\\\\\"\\\\u{4fe1}\\\\u{606f}\\\\u{53d1}\\\\u{9001}\\\\u{6210}\\\\u{529f}\\\\u{ff01}\\\\\\\",\\\\n inboxTitle: \\\\\\\"\\\\u{1f4e5} \\\\u{60a8}\\\\u{7684}\\\\u{6536}\\\\u{4ef6}\\\\u{7bb1}\\\\\\\",\\\\n from: \\\\\\\"\\\\u{6765}\\\\u{81ea}\\\\u{7684}\\\\u{6d88}\\\\u{606f}\\\\\\\",\\\\n reply: \\\\\\\"\\\\u{56de}\\\\u{590d}\\\\\\\",\\\\n footer: \\\\\\\"Global Messaging System by qelo.near\\\\\\\",\\\\n },\\\\n jp: {\\\\n title: \\\\\\\"NearGram\\\\\\\",\\\\n tagline: \\\\\\\"\\\\u{30b0}\\\\u{30ed}\\\\u{30fc}\\\\u{30d0}\\\\u{30eb}\\\\u{30fb}\\\\u{30aa}\\\\u{30f3}\\\\u{30c1}\\\\u{30a7}\\\\u{30fc}\\\\u{30f3}\\\\u{30fb}\\\\u{30e1}\\\\u{30c3}\\\\u{30bb}\\\\u{30fc}\\\\u{30b8}\\\\u{30f3}\\\\u{30b0}\\\\\\\",\\\\n recipientLabel: \\\\\\\"\\\\u{53d7}\\\\u{4fe1}\\\\u{8005}\\\\u{30a2}\\\\u{30c9}\\\\u{30ec}\\\\u{30b9}\\\\\\\",\\\\n recipientPlaceholder: \\\\\\\"\\\\u{4f8b}: qelo.near\\\\\\\",\\\\n messageLabel: \\\\\\\"\\\\u{30e1}\\\\u{30c3}\\\\u{30bb}\\\\u{30fc}\\\\u{30b8}\\\\\\\",\\\\n messagePlaceholder: \\\\\\\"\\\\u{3053}\\\\u{3053}\\\\u{306b}\\\\u{30e1}\\\\u{30c3}\\\\u{30bb}\\\\u{30fc}\\\\u{30b8}\\\\u{3092}\\\\u{5165}\\\\u{529b}...\\\\\\\",\\\\n sendBtn: \\\\\\\"\\\\u{30d6}\\\\u{30ed}\\\\u{30c3}\\\\u{30af}\\\\u{30c1}\\\\u{30a7}\\\\u{30fc}\\\\u{30f3}\\\\u{3067}\\\\u{9001}\\\\u{4fe1}\\\\\\\",\\\\n successMsg: \\\\\\\"\\\\u{9001}\\\\u{4fe1}\\\\u{5b8c}\\\\u{4e86}\\\\u{3057}\\\\u{307e}\\\\u{3057}\\\\u{305f}\\\\u{ff01}\\\\\\\",\\\\n inboxTitle: \\\\\\\"\\\\u{1f4e5} \\\\u{53d7}\\\\u{4fe1}\\\\u{30c8}\\\\u{30ec}\\\\u{30a4}\\\\\\\",\\\\n from: \\\\\\\"\\\\u{9001}\\\\u{4fe1}\\\\u{5143}:\\\\\\\",\\\\n reply: \\\\\\\"\\\\u{8fd4}\\\\u{4fe1}\\\\\\\",\\\\n footer: \\\\\\\"Global Messaging System by qelo.near\\\\\\\",\\\\n },\\\\n};\\\\n\\\\nState.init({\\\\n lang: \\\\\\\"id\\\\\\\",\\\\n recipient: props.recipient || \\\\\\\"\\\\\\\",\\\\n message: \\\\\\\"\\\\\\\",\\\\n showSuccess: false,\\\\n});\\\\n\\\\nconst currentT = T[state.lang];\\\\n\\\\n// 2. Data untuk Dikirim (DirapiKan)\\\\nconst composeData = {\\\\n index: {\\\\n notify: JSON.stringify({\\\\n key: state.recipient.toLowerCase().trim(),\\\\n value: {\\\\n type: \\\\\\\"neargram_message\\\\\\\",\\\\n message: state.message,\\\\n timestamp: Date.now(),\\\\n item: { type: \\\\\\\"social\\\\\\\", path: `qelo.near/widget/NEARgram` },\\\\n },\\\\n }),\\\\n },\\\\n};\\\\n\\\\n// 3. Styles (Premium Edition)\\\\nconst Theme = {\\\\n container: {\\\\n maxWidth: \\\\\\\"550px\\\\\\\",\\\\n margin: \\\\\\\"0 auto\\\\\\\",\\\\n fontFamily: \\\\\\\"Inter, sans-serif\\\\\\\",\\\\n },\\\\n card: {\\\\n borderRadius: \\\\\\\"28px\\\\\\\",\\\\n border: \\\\\\\"1px solid #eaeaea\\\\\\\",\\\\n boxShadow: \\\\\\\"0 10px 30px rgba(0,0,0,0.06)\\\\\\\",\\\\n padding: \\\\\\\"35px\\\\\\\",\\\\n backgroundColor: \\\\\\\"#fff\\\\\\\",\\\\n marginBottom: \\\\\\\"25px\\\\\\\",\\\\n },\\\\n titleHeader: {\\\\n fontWeight: \\\\\\\"900\\\\\\\",\\\\n fontSize: \\\\\\\"2.6rem\\\\\\\",\\\\n background: \\\\\\\"linear-gradient(45deg, #00ec97, #0093f2)\\\\\\\",\\\\n WebkitBackgroundClip: \\\\\\\"text\\\\\\\",\\\\n WebkitTextFillColor: \\\\\\\"transparent\\\\\\\",\\\\n },\\\\n button: {\\\\n borderRadius: \\\\\\\"16px\\\\\\\",\\\\n backgroundColor: \\\\\\\"#00ec97\\\\\\\",\\\\n color: \\\\\\\"#111\\\\\\\",\\\\n fontWeight: \\\\\\\"700\\\\\\\",\\\\n border: \\\\\\\"none\\\\\\\",\\\\n padding: \\\\\\\"16px\\\\\\\",\\\\n transition: \\\\\\\"all 0.2s\\\\\\\",\\\\n },\\\\n input: {\\\\n borderRadius: \\\\\\\"16px\\\\\\\",\\\\n backgroundColor: \\\\\\\"#f9fafb\\\\\\\",\\\\n border: \\\\\\\"1px solid #f3f4f6\\\\\\\",\\\\n padding: \\\\\\\"12px\\\\\\\",\\\\n fontSize: \\\\\\\"15px\\\\\\\",\\\\n },\\\\n notifCard: {\\\\n borderRadius: \\\\\\\"20px\\\\\\\",\\\\n background: \\\\\\\"#fff\\\\\\\",\\\\n borderLeft: \\\\\\\"5px solid #00ec97\\\\\\\",\\\\n border: \\\\\\\"1px solid #f0f0f0\\\\\\\",\\\\n padding: \\\\\\\"18px\\\\\\\",\\\\n marginBottom: \\\\\\\"12px\\\\\\\",\\\\n },\\\\n langSelect: {\\\\n borderRadius: \\\\\\\"12px\\\\\\\",\\\\n border: \\\\\\\"1px solid #eee\\\\\\\",\\\\n fontSize: \\\\\\\"13px\\\\\\\",\\\\n padding: \\\\\\\"6px 12px\\\\\\\",\\\\n outline: \\\\\\\"none\\\\\\\",\\\\n backgroundColor: \\\\\\\"#fff\\\\\\\",\\\\n },\\\\n};\\\\n\\\\n// 4. Komponen Tampilan Pesan Internal (Tahan Error)\\\\nconst renderMessage = (item) => {\\\\n const senderId = item.accountId;\\\\n const msg = item.value.message;\\\\n // Perbaikan Tanggal: Ditambah parseInt agar tidak \\\\\\'Invalid\\\\\\'\\\\n const time = item.value.timestamp\\\\n ? new Date(parseInt(item.value.timestamp)).toLocaleString(\\\\n state.lang === \\\\\\\"id\\\\\\\" ? \\\\\\\"id-ID\\\\\\\" : \\\\\\\"en-US\\\\\\\",\\\\n { hour: \\\\\\\"2-digit\\\\\\\", minute: \\\\\\\"2-digit\\\\\\\", day: \\\\\\\"numeric\\\\\\\", month: \\\\\\\"short\\\\\\\" }\\\\n )\\\\n : \\\\\\\"Baru saja\\\\\\\";\\\\n\\\\n return (\\\\n <div\\\\n style={Theme.notifCard}\\\\n className=\\\\\\\"d-flex align-items-center justify-content-between shadow-sm\\\\\\\"\\\\n >\\\\n <div className=\\\\\\\"d-flex align-items-center\\\\\\\">\\\\n <div className=\\\\\\\"me-3 fs-4\\\\\\\">\\\\u{2709}\\\\u{fe0f}</div>\\\\n <div>\\\\n <div\\\\n className=\\\\\\\"fw-bold\\\\\\\"\\\\n style={{ color: \\\\\\\"#0093f2\\\\\\\", fontSize: \\\\\\\"13px\\\\\\\" }}\\\\n >\\\\n {currentT.from} @{senderId}\\\\n </div>\\\\n <div\\\\n className=\\\\\\\"text-dark small\\\\\\\"\\\\n style={{ fontSize: \\\\\\\"14px\\\\\\\", marginTop: \\\\\\\"2px\\\\\\\" }}\\\\n >\\\\n {msg}\\\\n </div>\\\\n <div\\\\n className=\\\\\\\"text-muted\\\\\\\"\\\\n style={{ fontSize: \\\\\\\"10px\\\\\\\", marginTop: \\\\\\\"4px\\\\\\\" }}\\\\n >\\\\n {time}\\\\n </div>\\\\n </div>\\\\n </div>\\\\n <button\\\\n className=\\\\\\\"btn btn-sm\\\\\\\"\\\\n style={{\\\\n backgroundColor: \\\\\\\"#00ec97\\\\\\\",\\\\n fontWeight: \\\\\\\"700\\\\\\\",\\\\n borderRadius: \\\\\\\"11px\\\\\\\",\\\\n fontSize: \\\\\\\"11px\\\\\\\",\\\\n border: \\\\\\\"none\\\\\\\",\\\\n padding: \\\\\\\"6px 14px\\\\\\\",\\\\n }}\\\\n onClick={() => {\\\\n State.update({ recipient: senderId, showSuccess: false });\\\\n window.scrollTo(0, 0); // Auto-scroll ke atas\\\\n }}\\\\n >\\\\n <i className=\\\\\\\"bi bi-reply-fill me-1\\\\\\\"></i>\\\\n {currentT.reply}\\\\n </button>\\\\n </div>\\\\n );\\\\n};\\\\n\\\\nreturn (\\\\n <div className=\\\\\\\"py-5\\\\\\\" style={Theme.container}>\\\\n {/* BAGIAN KIRIM */}\\\\n <div style={Theme.card}>\\\\n {/* Pilihan Bahasa */}\\\\n <div className=\\\\\\\"d-flex justify-content-end mb-4\\\\\\\">\\\\n <select\\\\n style={Theme.langSelect}\\\\n onChange={(e) => State.update({ lang: e.target.value })}\\\\n value={state.lang}\\\\n >\\\\n <option value=\\\\\\\"id\\\\\\\">Indonesia</option>\\\\n <option value=\\\\\\\"en\\\\\\\">English (US)</option>\\\\n <option value=\\\\\\\"es\\\\\\\">Espa\\\\u{f1}ol</option>\\\\n <option value=\\\\\\\"fr\\\\\\\">Fran\\\\u{e7}ais</option>\\\\n <option value=\\\\\\\"zh\\\\\\\">\\\\u{4e2d}\\\\u{6587} (Chinese)</option>\\\\n <option value=\\\\\\\"jp\\\\\\\">\\\\u{65e5}\\\\u{672c}\\\\u{8a9e} (Japanese)</option>\\\\n </select>\\\\n </div>\\\\n\\\\n {/* Premium Header */}\\\\n <div className=\\\\\\\"text-center mb-5\\\\\\\">\\\\n <div className=\\\\\\\"d-flex align-items-center justify-content-center\\\\\\\">\\\\n <span className=\\\\\\\"fs-1 me-3\\\\\\\">\\\\u{26a1}</span>\\\\n <h1 style={Theme.titleHeader} className=\\\\\\\"mb-0\\\\\\\">\\\\n {currentT.title}\\\\n </h1>\\\\n </div>\\\\n <p className=\\\\\\\"text-secondary small mt-1 mb-0\\\\\\\">{currentT.tagline}</p>\\\\n </div>\\\\n\\\\n {/* Form Input */}\\\\n <div className=\\\\\\\"mb-3\\\\\\\">\\\\n <label className=\\\\\\\"form-label small fw-bold text-muted text-uppercase\\\\\\\">\\\\n {currentT.recipientLabel}\\\\n </label>\\\\n <input\\\\n type=\\\\\\\"text\\\\\\\"\\\\n className=\\\\\\\"form-control form-control-lg shadow-none\\\\\\\"\\\\n style={Theme.input}\\\\n placeholder={currentT.recipientPlaceholder}\\\\n value={state.recipient}\\\\n onChange={(e) =>\\\\n State.update({ recipient: e.target.value, showSuccess: false })\\\\n }\\\\n />\\\\n </div>\\\\n\\\\n <div className=\\\\\\\"mb-5\\\\\\\">\\\\n <label className=\\\\\\\"form-label small fw-bold text-muted text-uppercase\\\\\\\">\\\\n {currentT.messageLabel}\\\\n </label>\\\\n <textarea\\\\n className=\\\\\\\"form-control form-control-lg shadow-none\\\\\\\"\\\\n style={Theme.input}\\\\n rows=\\\\\\\"4\\\\\\\"\\\\n placeholder={currentT.messagePlaceholder}\\\\n value={state.message}\\\\n onChange={(e) =>\\\\n State.update({ message: e.target.value, showSuccess: false })\\\\n }\\\\n ></textarea>\\\\n </div>\\\\n\\\\n <CommitButton\\\\n disabled={!state.recipient || !state.message}\\\\n data={composeData}\\\\n onCommit={() => State.update({ message: \\\\\\\"\\\\\\\", showSuccess: true })}\\\\n className=\\\\\\\"btn w-100 shadow-sm\\\\\\\"\\\\n style={Theme.button}\\\\n >\\\\n <i className=\\\\\\\"bi bi-send-fill me-2\\\\\\\"></i> {currentT.sendBtn}\\\\n </CommitButton>\\\\n\\\\n {state.showSuccess && (\\\\n <div\\\\n className=\\\\\\\"alert alert-success mt-4 small text-center border-0 shadow-sm\\\\\\\"\\\\n style={{\\\\n borderRadius: \\\\\\\"14px\\\\\\\",\\\\n backgroundColor: \\\\\\\"#e8fbf0\\\\\\\",\\\\n color: \\\\\\\"#0d8246\\\\\\\",\\\\n fontWeight: \\\\\\\"600\\\\\\\",\\\\n }}\\\\n >\\\\n <i className=\\\\\\\"bi bi-check-circle-fill me-2\\\\\\\"></i>\\\\n {currentT.successMsg}\\\\n </div>\\\\n )}\\\\n </div>\\\\n\\\\n {/* BAGIAN INBOX */}\\\\n <div style={Theme.card}>\\\\n <h5 className=\\\\\\\"fw-bold mb-4\\\\\\\" style={{ color: \\\\\\\"#111\\\\\\\" }}>\\\\n {currentT.inboxTitle}\\\\n </h5>\\\\n <Widget\\\\n src=\\\\\\\"mob.near/widget/FilteredIndexFeed\\\\\\\"\\\\n props={{\\\\n index: {\\\\n action: \\\\\\\"notify\\\\\\\",\\\\n key: accountId,\\\\n options: { limit: 15, order: \\\\\\\"desc\\\\\\\", subscribe: true },\\\\n },\\\\n loading: (\\\\n <div\\\\n className=\\\\\\\"placeholder text-center text-muted small py-4\\\\\\\"\\\\n style={{ borderRadius: \\\\\\\"16px\\\\\\\" }}\\\\n >\\\\n Loading messages...\\\\n </div>\\\\n ),\\\\n renderItem: (item) => (\\\\n <div key={item.blockHeight}>\\\\n {item.value.type === \\\\\\\"neargram_message\\\\\\\"\\\\n ? renderMessage(item)\\\\n : null}\\\\n </div>\\\\n ),\\\\n }}\\\\n />\\\\n </div>\\\\n\\\\n {/* Footer */}\\\\n <div\\\\n className=\\\\\\\"text-center mt-5 text-secondary\\\\\\\"\\\\n style={{\\\\n fontSize: \\\\\\\"12px\\\\\\\",\\\\n borderTop: \\\\\\\"1px solid #eee\\\\\\\",\\\\n paddingTop: \\\\\\\"20px\\\\\\\",\\\\n }}\\\\n >\\\\n Developed by <strong>qelo.near</strong> \\\\u{2022} {currentT.footer}\\\\n </div>\\\\n </div>\\\\n);\\\\n" |