From f1db444853871b57ffb52132f4f427bf85ee749e Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 16 May 2026 18:44:40 +0700 Subject: [PATCH] Update --- chrom-ext/content.js | 45 ++++++++++++++++++++++++++++----------- chrom-ext/icons/icon.png | Bin 0 -> 1425 bytes 2 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 chrom-ext/icons/icon.png diff --git a/chrom-ext/content.js b/chrom-ext/content.js index 0f32c8b..f46b891 100644 --- a/chrom-ext/content.js +++ b/chrom-ext/content.js @@ -60,7 +60,7 @@ return [...TONE_BASE]; } function getAngles(tone) { - return tone === 'EMPATHETIC' ? [...ANGLE_DEFAULT,...ANGLE_EMPATHY] : [...ANGLE_DEFAULT]; + return tone === 'EMPATHETIC' ? [...ANGLE_DEFAULT, ...ANGLE_EMPATHY] : [...ANGLE_DEFAULT]; } // ===== A. CAPTURE TWEET ===== @@ -99,9 +99,8 @@ return false; }); - // ===== C. TYPING ENGINE (VIẾT LẠI) ===== + // ===== C. TYPING ENGINE ===== async function simulateHumanTyping(fullText) { - // Tìm ô reply của X let editor = document.querySelector('[data-testid="tweetTextarea_0"]') || document.querySelector('div[contenteditable="true"][role="textbox"]'); @@ -114,7 +113,6 @@ editor.focus(); editor.click(); - // Reset sạch: xóa hết, tạo 1 TextNode duy nhất để dễ manipulate editor.textContent = ''; const textNode = document.createTextNode(''); editor.appendChild(textNode); @@ -128,17 +126,13 @@ for (let i = 0; i < fullText.length; i++) { const char = fullText[i]; - - // 1. Thêm ký tự vào TextNode textNode.nodeValue += char; - // 2. Đẩy cursor về cuối range.setEnd(textNode, textNode.nodeValue.length); range.collapse(false); sel.removeAllRanges(); sel.addRange(range); - // 3. Báo cho React/Draft.js biết DOM đã đổi editor.dispatchEvent(new InputEvent('input', { bubbles: true, cancelable: true, @@ -146,7 +140,6 @@ data: char })); - // 4. Delay như người gõ thật let delay = 30 + Math.random() * 50; if (char === ' ') delay += 40 + Math.random() * 40; if ('.!?,'.includes(char)) delay += 120 + Math.random() * 200; @@ -154,7 +147,6 @@ await new Promise(r => setTimeout(r, delay)); } - // Final change event editor.dispatchEvent(new Event('change', { bubbles: true })); return true; } @@ -206,6 +198,8 @@ button.primary:disabled { background: #8ecdf7; cursor: default; } button.green { background: #17bf63 !important; } button.green:hover { background: #15a857 !important; } + button.gray { background: #536471 !important; } + button.gray:hover { background: #3e4e56 !important; } .status { display: none; padding: 12px; border-radius: 10px; font-size: 14px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; } .status.ok { background: #e8f6fe; border: 1px solid #b4dffc; } @@ -216,6 +210,8 @@ .typing-opts.visible { display: flex; } .check-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #0f1419; cursor: pointer; } .check-row input { cursor: pointer; } + .btn-row { display: flex; gap: 8px; } + .btn-row .primary { flex: 1; margin-top: 0; } `; const fab = document.createElement('button'); @@ -254,7 +250,10 @@ Giả lập gõ như người thật (từ từ) - +
+ + +
💡 Nếu chưa mở ô reply, hãy bấm Reply trước!
@@ -311,6 +310,7 @@ const typingOpts = drawer.querySelector('#ai-typing-opts'); const typingChk = drawer.querySelector('#ai-typing'); const pasteBtn = drawer.querySelector('#ai-paste'); + const copyBtn = drawer.querySelector('#ai-copy'); function populateSelect(sel, items, selectedValue) { sel.innerHTML = items.map(it => ``).join(''); @@ -365,6 +365,27 @@ ); }); + // COPY BUTTON + copyBtn.addEventListener('click', async () => { + const text = statusEl.textContent; + if (!text || text.startsWith('⏳') || text.startsWith('Lỗi') || text.startsWith('⚠️')) { + const old = copyBtn.textContent; + copyBtn.textContent = '⚠️ Chưa có nội dung!'; + setTimeout(() => copyBtn.textContent = old, 1200); + return; + } + try { + await navigator.clipboard.writeText(text); + const old = copyBtn.textContent; + copyBtn.textContent = '✅ Đã copy!'; + setTimeout(() => copyBtn.textContent = old, 1200); + } catch (e) { + const old = copyBtn.textContent; + copyBtn.textContent = '❌ Lỗi copy'; + setTimeout(() => copyBtn.textContent = old, 1200); + } + }); + // PASTE BUTTON pasteBtn.addEventListener('click', async () => { const text = statusEl.textContent; @@ -380,7 +401,7 @@ if (typingChk.checked) { pasteBtn.textContent = '⌨️ Đang gõ...'; const ok = await simulateHumanTyping(text); - if (ok) drawer.classList.remove('open'); // thu sidebar để người dùng thấy reply + if (ok) drawer.classList.remove('open'); } else { await navigator.clipboard.writeText(text); alert('✅ Đã copy vào clipboard!\n\nBạn tự dán vào ô reply nhé.'); diff --git a/chrom-ext/icons/icon.png b/chrom-ext/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a014abcf4b043162a5a2dd39dbdb31f21fc39bcd GIT binary patch literal 1425 zcmZ`(2~d+)5PoO{OKZ_yQnjtM)q0dR;?b5`>j4VNC1ODZ6$ns7PJ@UjB9{uvk&1u@ z3J4?+u1IbY5^_LD0wII|fg~JBI88u-9OBWRai$$-+MRj3Z@;(S?t3$D_qMz1;T4u^ zECB#3oE+^vAiHvLEnf=h%{ErYA+tWf(ZdCRE1LjFOab6I1SO6G5Ca2X@*Dtm`2ehr zL{X3J0bq&F-PzLt3TSG%!xg3-bYIm!NF330ld-tgu2QNXCj)z;5TB_Y9?c~L7Ll)w zsJbiZ85BMmON>=0YsV+5XXkp1CY|Z|+}ylye5!b0D3jQ9O&~6nD5|)9Su@Yd#wJNJ zxqvAw=#p1Um8CfLo!qKZY)QI!0M*P*C$v5k$m)BPH`(Ib1TLywQb6HHaXard@Pj0B zGE-cHW#6T@)#j1nl~Ur}nm8#pVML6<@nZ436e_8_f)rZGyrop((lK5cwXRte;Z^if z6geuh&M%)7bhX$myDqebmDRvP71Lud3c8>p=^8(S5@W10&So zQPHGUJTS~qs+zS=JIA%GepOXRe?i9pRwREcS2G8cI8ko_sV(3k{zwVlOW2;L9^(v- zvZRU!B1uhmPqk)JDwEZf6(`n_1B%IqFijq{_~4kBvyIFgg__VQ%@TEI)7Y1I9ce?F zb|NJsEXoB-@M-Dt<%!NPT70TXyxEKd^(eWkH-ph~i9m`H@FT^26++IHepaZEc3P5s zsxQsAz5Jw_b6(B}<#${c3d5dzAgk7)|@Q+R!Ak%4~SsKFa_WNCkVi`1{23a{p*^+{-0 zN-~A-E9ecL(3F{GXohL3K}Rv_sIyb`B3VQY)4PI}g2cy@Y594z?wl@v?Rceex>2vA z=(QAs7SaTsBsv@8T+x_{BKQC#2&7HJbCp226T7X2QLZcV`MSSu6P2|7K z4P#bYpsZ&8M-SVZoZ((GkYj;xa&fSjTxMlyzHObUCmMn_A{@LCa6d$#T|jgoWPmNq zcDD^|m(BKFp4(w|u-$e$ZMVUo4Q#J`%k{SiVG;0 zg+=}cXUCf&O{zu=bm_HD_WM1pC1xwlre8rR%vOE)(Z`>By4w1)HA^6O={sxJeSYG1 zFYlA5zW8$eGIL<@)rQkPzGu#!^YagYfBnsJuyIphQ1Bli=R+@qg-1kwyBTcR8WnvJ z5pyZ_a@>{ptJ}TdFyui_uz+&J9jg)vU8As-pjq8mk$Hm3m!Z~ z6&C$fTvGa|th~Y&>_B5GtFYBIwRQEl#|`+MU>AW%B2%c1GvZ zzChUCA?o}I{A?%gl5|UZdi!Mk1M*+?fM542l!HUVBPz9KbZq>$ec;{w2PP(`o@jN` zGf$r#w6_HBz3*`7@a){Y-e7ceId!2_k_kQcm3tU0-LRiLl-zX LxZ2kqIG6M{u7e4k literal 0 HcmV?d00001