twitter.js 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120
  1. import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
  2. import { throttle, getQueryString, getCookie, nextTick, getQueryStringByUrl } from '@/uilts/help'
  3. import { discordAuthRedirectUri } from '@/http/configAPI'
  4. import { reportSrcPublishEvent } from '@/http/publishApi'
  5. import Report from "@/log-center/log"
  6. import { fetchAddFinishEvent } from '@/logic/background/fetch/facebook';
  7. import { showNFTGroupIcon, hideNFTGroupList, checkUserJoinGroup, elemAddEventListener, addJoinedGroupList } from '@/logic/content/nft';
  8. import { getTwitterNftGroupInfo } from '@/http/nft'
  9. import { jumpTwitterDetailByAlert } from '@/logic/content/help/twitter.js'
  10. let dom = {};
  11. let tweetAccountBindGroupInfo = {
  12. isBind: false,
  13. groupInfo: null,
  14. isInit: false
  15. }
  16. let systemInfo = {
  17. theme: 'light'
  18. }
  19. function twitterPinLogin() {
  20. if (window.location.href == 'https://api.twitter.com/oauth/authorize') {
  21. let code = document.querySelector('code')
  22. if (code) {
  23. chrome.runtime.sendMessage({ actionType: "CONTENT_SEND_CODE", code: code.innerText }, () => { })
  24. // port.postMessage({ state: 'CONTENT_SEND_CODE', code: code.innerText })
  25. }
  26. }
  27. }
  28. function getDiscordAuthCode() {
  29. if (window.location.href.indexOf(discordAuthRedirectUri) > -1) {
  30. const urlParams = new URLSearchParams(window.location.search);
  31. const code = urlParams.get('code');
  32. if (code) {
  33. chrome.runtime.sendMessage({ actionType: "CONTENT_SEND_DISCORD_AUTH_CODE", code }, () => { })
  34. }
  35. }
  36. };
  37. /**
  38. * 渲染要插入的dom,初始化逻辑
  39. * @param port
  40. */
  41. function renderDom() {
  42. if (window.location.href.indexOf('https://twitter.com') > -1) {
  43. _createBtnDom();
  44. onWindowResize();
  45. checkHasDeBtn();
  46. setTimeout(() => {
  47. _addIframe();
  48. _addDeNetBtn();
  49. _getSliderTwitterBtn();
  50. }, 800)
  51. }
  52. }
  53. /**
  54. * 展示give弹窗
  55. */
  56. export function showGiveDialogHandler(userInfo) {
  57. let iframe = document.getElementById('iframe-content');
  58. if (iframe) {
  59. iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', userInfo }, '*');
  60. } else {
  61. _addIframe();
  62. let iframe = document.getElementById('iframe-content');
  63. iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', userInfo }, '*');
  64. }
  65. }
  66. export function showIframeHandler() {
  67. document.getElementById('iframe-content').style.display = 'block';
  68. }
  69. export function hideIframeHandler() {
  70. document.getElementById('iframe-content').style.display = 'none';
  71. }
  72. /**
  73. * 展示twitter原生发布框
  74. */
  75. let tweetPublishStore = {
  76. showPublishDialog: false
  77. }
  78. export function showTwitterPublishDialogHandler(publishRes) {
  79. let bigBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
  80. if (bigBtn) {
  81. bigBtn.click();
  82. tweetPublishStore.showPublishDialog = true;
  83. } else {
  84. let smallBtn = document.querySelector('a[href="/compose/tweet"]')
  85. smallBtn && smallBtn.click();
  86. tweetPublishStore.showPublishDialog = true;
  87. }
  88. setChromeStorage({ publishData: JSON.stringify(publishRes) })
  89. addPublishTipsIframe({
  90. srcContent: publishRes.copyContent
  91. })
  92. _setPublishContent(publishRes.srcContent);
  93. _publishTweetEvent(publishRes, bindTwitterArtMethod);
  94. }
  95. export function twitterPublishHandler(res) {
  96. let bigBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
  97. if (bigBtn) {
  98. bigBtn.click();
  99. } else {
  100. let smallBtn = document.querySelector('a[href="/compose/tweet"]')
  101. smallBtn && smallBtn.click();
  102. }
  103. nextTick(() => {
  104. document.execCommand('selectAll');
  105. }, 100).then(() => {
  106. _setPublishContent(res.srcContent, 500);
  107. })
  108. }
  109. export function showPinTips() {
  110. hidePopupPage();
  111. hideNoticeBindTweet();
  112. getChromeStorage('pinData', (res) => {
  113. if (!res || res.show) {
  114. let domPop = document.getElementById('de-pin-pop');
  115. domPop.style.display = 'block';
  116. }
  117. })
  118. }
  119. export function hidePinTips() {
  120. let pop = document.querySelector('#de-pin-pop');
  121. if (pop) {
  122. pop.style.display = 'none';
  123. }
  124. }
  125. function addPinedPop() {
  126. let domPop = document.getElementById('de-pin-pop');
  127. if (domPop) {
  128. return;
  129. }
  130. let popWrapper = document.createElement('div');
  131. popWrapper.style.cssText = 'position: fixed; height: 400px;width: 300px;top: 12px;right: 20px;border-radius: 12px;border: 0.5px solid #919191;box-sizing: border-box;padding: 20px;background: #fff;display:none';
  132. popWrapper.id = 'de-pin-pop'
  133. let img = document.createElement('img');
  134. img.src = require("@/assets/img/img-pined-guide.png");
  135. img.width = 253;
  136. let contentDom = document.createElement('div');
  137. contentDom.innerHTML = "<div style='font-weight: 500;font-size: 18px;margin-top: 20px;margin-bottom: 20px'>📌 Pin an Extension is more convenient to open😄</div><div style='display: flex; align-items: center; justify-content: space-between;'><div style='display: flex; align-items: center; font-size: 14px; color: #899099; cursor: pointer;' id='de-remind'><input id='de-check' type='checkbox'/> Don't remind</div><div class='de-pin-skip' style='font-weight: 500; font-size: 16px; color: #1D9BF0;cursor: pointer;'>Skip</div></div>"
  138. popWrapper.appendChild(img);
  139. popWrapper.appendChild(contentDom);
  140. document.querySelector('body').appendChild(popWrapper);
  141. let deCheck = document.querySelector('#de-check');
  142. let deRemind = document.querySelector('#de-remind');
  143. deCheck.onclick = function (e) {
  144. e && e.stopPropagation && e.stopPropagation();
  145. setChromeStorage({ pinData: JSON.stringify({ show: !this.checked }) })
  146. }
  147. deRemind.onclick = function () {
  148. deCheck.checked = !deCheck.checked;
  149. setChromeStorage({ pinData: JSON.stringify({ show: !deCheck.checked }) })
  150. }
  151. document.querySelector('.de-pin-skip').onclick = function () {
  152. document.querySelector('#de-pin-pop').style.display = 'none';
  153. }
  154. }
  155. function getUserInfo(cb) {
  156. getChromeStorage('userInfo', (res) => {
  157. cb && cb(res);
  158. })
  159. }
  160. // 绑定推文id所需参数
  161. let bindTwitterArt = {
  162. needBind: false,
  163. postId: '',
  164. isBindIng: false
  165. };
  166. /**
  167. * 监听dialog内点击原生发布按钮事件
  168. * @private
  169. */
  170. function _publishTweetEvent(params, cb) {
  171. setTimeout(() => {
  172. let publishTweetBtn;
  173. let dialog = document.querySelector('div[role="dialog"]');
  174. if (dialog) {
  175. publishTweetBtn = dialog.querySelector('div[data-testid="tweetButton"]');
  176. onClosePublishDialogHandle(dialog, params)
  177. } else {
  178. let domMain = document.querySelector('main[role="main"]');
  179. publishTweetBtn = domMain && domMain.querySelector('div[data-testid="tweetButton"]');
  180. }
  181. publishTweetBtn && publishTweetBtn.addEventListener('click', function () {
  182. bindTwitterArt.needBind = true;
  183. bindTwitterArt.postId = params.postId;
  184. tweetPublishStore.showPublishDialog = false;
  185. // checkIsShowReSend(dialog, params);
  186. cb && cb()
  187. });
  188. }, 800)
  189. }
  190. function onClosePublishDialogHandle(dom, params) {
  191. dom.querySelector('div[role="group"]').addEventListener('click', function () {
  192. setTimeout(() => {
  193. let parent = document.querySelector('div[data-testid="confirmationSheetDialog"]');
  194. if (parent) {
  195. let btnArr = parent.querySelectorAll('div[role=button]')
  196. for (let i = 0; i < btnArr.length; i++) {
  197. let btn = btnArr[i];
  198. btn.addEventListener('click', function () {
  199. tweetPublishStore.showPublishDialog = false;
  200. let taskLuckdropId = JSON.parse(params.postBizData).taskLuckdropId;
  201. noticeBindTweet({ postId: params.postId, taskLuckdropId });
  202. })
  203. }
  204. } else {
  205. setTimeout(() => {
  206. let dialog = document.querySelector('div[role="dialog"]');
  207. if (!dialog) {
  208. tweetPublishStore.showPublishDialog = false;
  209. }
  210. }, 800)
  211. }
  212. }, 1000)
  213. })
  214. }
  215. function checkIsShowReSend(dom, params) {
  216. let str = dom.querySelector('div[data-contents="true"]').innerHTML;
  217. if (str.indexOf(params.postId) < 0) {
  218. let taskLuckdropId = JSON.parse(params.postBizData).taskLuckdropId;
  219. noticeBindTweet({ postId: params.postId, taskLuckdropId });
  220. }
  221. }
  222. /**
  223. * 在输入推文区插入deNet按钮
  224. * @param parent
  225. * @param dom
  226. * @param isClick
  227. * @private
  228. */
  229. function _addDeNetEditBtn(parent, dom, isClick = false) {
  230. setTimeout(() => {
  231. if (parent && parent.parentNode) {
  232. Report.reportLog({
  233. pageSource: Report.pageSource.mainPage,
  234. businessType: Report.businessType.buttonView,
  235. objectType: Report.objectType.buttonSecond
  236. });
  237. let innerDeIcon = document.getElementById('de-btn1');
  238. if (!innerDeIcon) {
  239. parent.parentNode.insertBefore(dom, parent.nextElementSibling);
  240. }
  241. } else {
  242. setTimeout(() => {
  243. parent = _getScheduleDom(isClick);
  244. if (parent && parent.parentNode) {
  245. Report.reportLog({
  246. pageSource: Report.pageSource.mainPage,
  247. businessType: Report.businessType.buttonView,
  248. objectType: Report.objectType.buttonSecond
  249. });
  250. let innerDeIcon = document.getElementById('de-btn1');
  251. if (!innerDeIcon) {
  252. parent.parentNode.insertBefore(dom, parent.nextElementSibling);
  253. }
  254. }
  255. }, 1000)
  256. }
  257. })
  258. }
  259. /**
  260. * 在dialog插入deNet按钮
  261. * @private
  262. */
  263. // function _addDeNetBtnToDialog() {
  264. // setTimeout(() => {
  265. // let dialogScheduleBtn = _getScheduleDom(true);
  266. // _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn2);
  267. // }, 800)
  268. // }
  269. /**
  270. * 获取左侧twitter按钮
  271. * @private
  272. */
  273. function _getSliderTwitterBtn() {
  274. dom.tweetBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
  275. dom.tweetBtn.addEventListener('click', function () {
  276. // _addDeNetBtnToDialog();
  277. })
  278. }
  279. /**
  280. * 添加deNet按钮
  281. * @private
  282. */
  283. function _addDeNetBtn() {
  284. setTimeout(() => {
  285. let navWidth = document.querySelector('nav[role="navigation"]').offsetWidth;
  286. addSliderNavDeBtn(navWidth < 245);
  287. let innerDeIcon = document.getElementById('de-btn1');
  288. if (!innerDeIcon) {
  289. let dialogScheduleBtn = _getScheduleDom(false);
  290. dom && dom.deBtn1 && _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn1);
  291. }
  292. }, 800)
  293. }
  294. /**
  295. * 获取推文输入框内dom,用于插入deNet
  296. * @param isDialogInner
  297. * @returns {Element}
  298. * @private
  299. */
  300. function _getScheduleDom(isDialogInner = false) {
  301. let scheduleBtn;
  302. if (isDialogInner) {
  303. scheduleBtn = document.querySelector('div[role="dialog"]').querySelector('[data-testid="createPollButton"]');
  304. } else {
  305. let toolBar = document.querySelector('div[data-testid="toolBar"]');
  306. if (toolBar) {
  307. scheduleBtn = toolBar.querySelector('div[data-testid="geoButton"]');
  308. }
  309. }
  310. return scheduleBtn;
  311. }
  312. /**
  313. * 插入iframe到页面
  314. * @private
  315. */
  316. function _addIframe() {
  317. // let span = document.createElement('span');
  318. // const shadowRoot = span.attachShadow({mode: 'closed'})
  319. let iframe = document.createElement('iframe');
  320. iframe.src = chrome.runtime.getURL('/iframe/publish.html')
  321. iframe.id = 'iframe-content'
  322. iframe.style.cssText = 'position:fixed;top:0px;right:0;display:block; width:100%;height:100%;z-index:10000; border: medium none;display:none';
  323. // shadowRoot.appendChild(iframe);
  324. // document.body.appendChild(span)
  325. dom.iframe = iframe;
  326. let iframeContent = document.getElementById('iframe-content');
  327. if (!iframeContent) {
  328. document.querySelector('body').appendChild(iframe);
  329. }
  330. }
  331. function addPublishTipsIframe(params = {}) {
  332. let { time = 1000 } = params;
  333. setTimeout(() => {
  334. let dialog = document.querySelector('div[role="dialog"]').querySelector('div[role="dialog"]')
  335. if (dialog) {
  336. let right = dialog.offsetLeft - 15 - 266;
  337. let iframe = document.createElement('iframe');
  338. iframe.id = 'de-publish-tips'
  339. if (params.type == 'nft') {
  340. iframe.src = chrome.runtime.getURL('/iframe/publish-tips.html?type="nft"');
  341. } else {
  342. iframe.src = chrome.runtime.getURL('/iframe/publish-tips.html');
  343. }
  344. iframe.style.cssText = `border: medium none; width:270px;height:500px;position: fixed; right: ${right}px; top: 5%;z-index: -1`
  345. let iframeContent = document.getElementById('de-publish-tips');
  346. if (!iframeContent) {
  347. dialog.appendChild(iframe)
  348. }
  349. }
  350. }, time)
  351. }
  352. export function noticeBindTweet(params) {
  353. hidePinTips();
  354. hidePopupPage();
  355. let iframe = document.createElement('iframe');
  356. iframe.id = 'de-notice-bind-tweet';
  357. iframe.src = chrome.runtime.getURL('/iframe/bind-tweet.html') + `?params=${JSON.stringify(params)}`;
  358. iframe.style.cssText = `border: medium none; width:400px;min-height:313px;position: fixed; right: 16px; top: 16px;`
  359. let iframeContent = document.getElementById('de-notice-bind-tweet');
  360. if (!iframeContent) {
  361. document.querySelector('body').appendChild(iframe)
  362. }
  363. }
  364. export function hideNoticeBindTweet() {
  365. let iframeContent = document.getElementById('de-notice-bind-tweet');
  366. if (iframeContent) {
  367. document.querySelector('body').removeChild(iframeContent)
  368. }
  369. }
  370. /**
  371. * 点击deNet按钮处理
  372. * @private
  373. */
  374. function _deNetBtnClick() {
  375. getUserInfo((res) => {
  376. if (res) {
  377. if (window.location.pathname != '/home') {
  378. if (!dom.homeBtn) {
  379. dom.homeBtn = document.querySelector('a[data-testid="AppTabBar_Home_Link"]');
  380. }
  381. dom.homeBtn.click();
  382. }
  383. showGiveDialogHandler(res);
  384. } else {
  385. let loadIcon = document.getElementById('de-btn-loading');
  386. if (loadIcon) {
  387. return;
  388. }
  389. dom && dom.deBtn && dom.deBtn.insertBefore(dom.loadingImg, dom.deBtn.querySelector('span'));
  390. setTimeout(() => {
  391. dom.loadingImg.style.transform = 'rotate(1080deg)'
  392. });
  393. setTimeout(() => {
  394. dom.loadingImg.style.transform = 'rotate(0deg)'
  395. dom.deBtn.innerHTML = '<span>DeNet<span>';
  396. }, 2000)
  397. chrome.runtime.sendMessage({ actionType: "CONTENT_TWITTER_LOGIN", data: '1' }, (res) => { console.log(res) })
  398. }
  399. })
  400. }
  401. /**
  402. * 设置发布内容
  403. * @param content
  404. * @private
  405. */
  406. let isSetContent = false;
  407. export const _setPublishContent = throttle(function (content, time = 1000) {
  408. if (!isSetContent) {
  409. isSetContent = true;
  410. let inputEle = document.querySelector('div[contenteditable="true"]');
  411. if (inputEle) {
  412. inputEle.focus();
  413. }
  414. setTimeout(() => {
  415. document.execCommand("insertText", false, content);
  416. setTimeout(() => {
  417. isSetContent = false;
  418. }, 2000)
  419. }, time);
  420. }
  421. }, 800);
  422. /**
  423. * 创建deNet按钮 添加到页面
  424. * @returns {{deBtn2: HTMLDivElement, deBtn1: HTMLDivElement, deBtn: HTMLSpanElement}}
  425. * @private
  426. */
  427. function _createBtnDom() {
  428. let loadingImg = document.createElement('img');
  429. loadingImg.id = 'de-btn-loading'
  430. loadingImg.src = require("@/assets/img/icon-btn-loading.png");
  431. loadingImg.style.cssText = 'width:20px;height: 20px;margin-right:3px;transition-duration: 3s;';
  432. let style = document.createElement('style');
  433. style.innerHTML = "#de-btn:hover{opacity: .9;};@-webkit-keyframes load{from{ transform: rotate(0deg);} to{transform: rotate(360deg);}}";
  434. document.getElementsByTagName('head').item(0).appendChild(style);
  435. // 左侧大屏按钮
  436. let deBtn = document.createElement('span');
  437. // const shadowDiv = document.createElement('div');
  438. deBtn.innerHTML = '<span>DeNet</span>';
  439. deBtn.id = 'de-btn';
  440. deBtn.style.cssText = 'width:90%;height: 52px;text-align:center;line-height:52px;margin-bottom: 4px;margin-top: 4px;background: linear-gradient(274.8deg, #FF9900 -3.69%, #BD00FF 69.71%, #00F0FF 122.65%);color:#fff;font-size:17px;font-weight:700;border-radius:100px;cursor: pointer;display: flex;align-items: center;justify-content: center;';
  441. // 编辑框内按钮
  442. const deBtn1 = document.createElement('img');
  443. let src = require("@/assets/img/icon-gift-pack.png");
  444. const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;padding: 0px 8px';
  445. deBtn1.id = 'de-btn1';
  446. deBtn1.style.cssText = smallDeBtnStyle;
  447. deBtn1.src = src
  448. const deBtn2 = document.createElement('div');
  449. deBtn2.id = 'de-btn2';
  450. deBtn2.style.cssText = smallDeBtnStyle;
  451. deBtn2.src = "@/assets/img/icon-gift-pack.png"
  452. // 小屏按钮
  453. const deBtn3 = document.createElement('img');
  454. deBtn3.id = 'de-btn3'
  455. deBtn3.src = require("@/assets/logo/128.png");
  456. deBtn3.style.cssText = 'width:52px;height: 52px;margin-top:20px;cursor: pointer;';
  457. deBtn.addEventListener('click', () => {
  458. // chrome.runtime.sendMessage({
  459. // actionType: 'CONTENT_SET_BADGE',
  460. // data: {
  461. // text: '2'
  462. // }
  463. // }, res => {
  464. // console.log(res);
  465. // })
  466. Report.reportLog({
  467. pageSource: Report.pageSource.mainPage,
  468. businessType: Report.businessType.buttonClick,
  469. objectType: Report.objectType.buttonMain
  470. });
  471. _deNetBtnClick();
  472. })
  473. deBtn1.addEventListener('click', () => {
  474. Report.reportLog({
  475. pageSource: Report.pageSource.mainPage,
  476. businessType: Report.businessType.buttonClick,
  477. objectType: Report.objectType.buttonSecond
  478. });
  479. _deNetBtnClick();
  480. })
  481. deBtn2.addEventListener('click', () => {
  482. _deNetBtnClick();
  483. })
  484. deBtn3.addEventListener('click', () => {
  485. Report.reportLog({
  486. pageSource: Report.pageSource.mainPage,
  487. businessType: Report.businessType.buttonClick,
  488. objectType: Report.objectType.buttonMain
  489. });
  490. _deNetBtnClick();
  491. })
  492. dom.deBtn = deBtn;
  493. dom.deBtn1 = deBtn1;
  494. dom.deBtn2 = deBtn2;
  495. dom.deBtn3 = deBtn3;
  496. dom.loadingImg = loadingImg;
  497. }
  498. function addSliderNavDeBtn(isSmall = false) {
  499. if (!isSmall) {
  500. let bigDom = document.querySelector('a[href="/compose/tweet"]').parentNode.parentNode;
  501. let deBtn = document.getElementById('de-btn');
  502. if (bigDom && !deBtn) {
  503. dom && dom.deBtn && bigDom.appendChild(dom.deBtn);
  504. Report.reportLog({
  505. pageSource: Report.pageSource.mainPage,
  506. businessType: Report.businessType.buttonView,
  507. objectType: Report.objectType.buttonMain
  508. });
  509. }
  510. } else {
  511. let smallDom = document.querySelector('a[href="/compose/tweet"]').parentNode.parentNode;
  512. let deBtn3 = document.getElementById('de-btn3');
  513. if (smallDom && !deBtn3) {
  514. dom && dom.deBtn3 && smallDom.appendChild(dom.deBtn3);
  515. Report.reportLog({
  516. pageSource: Report.pageSource.mainPage,
  517. businessType: Report.businessType.buttonView,
  518. objectType: Report.objectType.buttonMain
  519. });
  520. }
  521. }
  522. }
  523. function onWindowResize() {
  524. window.onresize = throttle(function () {
  525. setTabGroupIframeStyle();
  526. try {
  527. if (tweetPublishStore.showPublishDialog) {
  528. let dialog = document.querySelector('div[role="dialog"]');
  529. let dePublishTips = document.getElementById('de-publish-tips');
  530. if (dialog && !dePublishTips) {
  531. addPublishTipsIframe({ time: 0 });
  532. } else if (dialog && dePublishTips) {
  533. let dialogContent = dialog.querySelector('div[role=dialog]')
  534. if (dialogContent) {
  535. let right = dialogContent.offsetLeft - 15 - 266;
  536. dePublishTips.style.right = right + 'px';
  537. }
  538. }
  539. }
  540. if (window.innerWidth < 1273) {
  541. let bigBtn = document.querySelector('#de-btn');
  542. bigBtn && bigBtn.remove();
  543. setTimeout(() => {
  544. addSliderNavDeBtn(true);
  545. })
  546. } else {
  547. let smallBtn = document.querySelector('#de-btn3');
  548. smallBtn && smallBtn.remove();
  549. setTimeout(() => {
  550. addSliderNavDeBtn()
  551. })
  552. }
  553. } catch (e) {
  554. console.log(e)
  555. }
  556. }, 800)
  557. }
  558. function checkHasDeBtn() {
  559. try {
  560. let toolBar = document.querySelector('div[data-testid="toolBar"]');
  561. let innerDeIcon = document.getElementById('de-btn1');
  562. if (toolBar && !innerDeIcon) {
  563. let dialogScheduleBtn = _getScheduleDom(false);
  564. dom && dom.deBtn1 && _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn1);
  565. }
  566. } catch (e) {
  567. console.log(e)
  568. }
  569. }
  570. /**
  571. * 点击发推,后端绑定推特id
  572. */
  573. function bindTwitterArtMethod() {
  574. if (!bindTwitterArt.postId) {
  575. return
  576. }
  577. if (bindTwitterArt.needBind && !bindTwitterArt.isBindIng) {
  578. bindTwitterArt.isBindIng = true;
  579. reportSrcPublishEvent({
  580. params: {
  581. postId: bindTwitterArt.postId,
  582. }
  583. }).then((res) => {
  584. if (res.code == 0) {
  585. Report.reportLog({
  586. objectType: Report.objectType.tweetPostBinded
  587. });
  588. bindTwitterArt.needBind = false;
  589. bindTwitterArt.postId = '';
  590. bindTwitterArt.isBindIng = false;
  591. }
  592. })
  593. }
  594. }
  595. import parseCard from './ParseCard'
  596. import { renderThumbStyle } from 'element-plus'
  597. import { defaultNavigator } from '_@vueuse_core@8.7.4@@vueuse/core'
  598. // 检测dom改变
  599. // 获取短链接
  600. // 查看本地是否有postid
  601. // 如果有 修改dom 返回
  602. // 如果没有 网络请求
  603. // 获取postid
  604. // 获取twitterid
  605. // 检测当前所有dom 如果没有
  606. let queue_num = 1
  607. export const changeQueueNum = (num = 0) => {
  608. queue_num = queue_num + num
  609. if (queue_num > 5) {
  610. queue_num = 5
  611. }
  612. }
  613. let main_observer = null
  614. function onChangePageMain(targetNode) {
  615. try {
  616. const config = { attributes: false, childList: true, subtree: true };
  617. const callback = (mutationsList, observer) => {
  618. changeQueueNum(1)
  619. }
  620. main_observer = new MutationObserver(callback);
  621. main_observer.observe(targetNode, config);
  622. } catch (error) {
  623. main_observer = null
  624. }
  625. }
  626. // 1.监听main改变
  627. // 2.监听卡片是否可见
  628. // 3.如果可见了 去找
  629. function setIframeRedPacket(type = 'twitter') {
  630. // 获取所有卡片参数
  631. let card_json_data
  632. switch (type) {
  633. case 'facebook':
  634. card_json_data = parseCard.parseFacebookCardParmas()
  635. for (let i in card_json_data) {
  636. parseCard.replaceFacebookPacket(card_json_data[i])
  637. }
  638. break;
  639. default:
  640. card_json_data = parseCard.parseAllDeNetCardParmas()
  641. // 过滤出可以请求的短链接
  642. parseCard.getCardParmas(card_json_data).then((res) => {
  643. for (let i in res.has_post_Id_card_data) {
  644. let item = res.has_post_Id_card_data[i];
  645. if (item && item.post_Id && item.post_Id.indexOf('nft/') >= 0) {
  646. parseCard.replaceNftDomRedPacket(item)
  647. } else if (item && item.post_Id && item.post_Id.indexOf('nft_group/') >= 0) {
  648. parseCard.replaceNftGroupDomRedPacket(item)
  649. } else {
  650. parseCard.replaceDOMRedPacket(item)
  651. }
  652. }
  653. if (res.need_net_short_url.length > 0) {
  654. // 请求短链接
  655. chrome.runtime.sendMessage({ actionType: "CONTENT_TWITTER_SHORT_LINK", data: "", arr_url: res.need_net_short_url }, () => { })
  656. }
  657. })
  658. break;
  659. }
  660. }
  661. // 监听点击发推 上报文案
  662. // document.addEventListener('click', (e) => {
  663. // try {
  664. // let inputEle = document.querySelector('div[contenteditable="true"]');
  665. // if (e.target.dataset && e.target.dataset.testid && e.target.dataset.testid == 'tweetButton') {
  666. // // 获取文案上报
  667. // console.log(inputEle.innerText)
  668. // } else if (e.target.closest('div[data-testid=tweetButton]')) {
  669. // console.log(inputEle.innerText)
  670. // }
  671. // } catch (error) {
  672. // console.error('error', error)
  673. // }
  674. // })
  675. export function initExecuteScript(changes) {
  676. if (changes.executeScript) {
  677. let item = JSON.parse(changes.executeScript.newValue)
  678. if (item.executeScript) {
  679. init()
  680. }
  681. }
  682. }
  683. const createNFTIframe = ({ url, id }, callback) => {
  684. let iframe = document.createElement('iframe')
  685. iframe.id = id
  686. iframe.src = url
  687. iframe.style.cssText = 'border:medium none; width:100%; height:100%; z-index:100; position: fixed; top:0;left:0; display:none;';
  688. iframe.onload = () => {
  689. callback && callback()
  690. }
  691. document.body.appendChild(iframe);
  692. }
  693. function initParseCard() {
  694. let timer = setInterval(() => {
  695. let inTwitter = window.location.href.includes('twitter.com');
  696. let inTwitterNode = document.querySelector('main');
  697. let inFacebook = window.location.href.includes('facebook.com');
  698. let inFacebookNode = document.querySelector('#facebook');
  699. if (inTwitter && inTwitterNode) {
  700. clearInterval(timer)
  701. setInterval(() => {
  702. if (!main_observer) {
  703. onChangePageMain(inTwitterNode)
  704. changeQueueNum(1)
  705. }
  706. showNFTGroupIcon()
  707. if (queue_num <= 0) {
  708. return
  709. }
  710. setIframeRedPacket()
  711. checkHasDeBtn()
  712. checkHasSliderDeBtn();
  713. changeQueueNum(-1)
  714. showNFTCard()
  715. initGroupTip()
  716. addGroupTab();
  717. addJoinedGroupList();
  718. }, 1000)
  719. } else if (inFacebook && inFacebookNode) {
  720. clearInterval(timer)
  721. setInterval(() => {
  722. if (!main_observer) {
  723. onChangePageMain(inFacebookNode)
  724. changeQueueNum(1)
  725. }
  726. if (queue_num <= 0) {
  727. return
  728. }
  729. setIframeRedPacket('facebook')
  730. changeQueueNum(-1)
  731. }, 1000)
  732. }
  733. }, 1000);
  734. }
  735. let inited = false
  736. // 初始化
  737. export function init() {
  738. if (inited) {
  739. return
  740. }
  741. inited = true
  742. console.log('init')
  743. getDiscordAuthCode();
  744. appendPopupPage();
  745. chrome.runtime.sendMessage({
  746. actionType: "CONTENT_SET_POPUP_CONFIG",
  747. data: {
  748. popup: 'popup.html'
  749. }
  750. }, () => { });
  751. let where = window.location.href.indexOf('twitter.com') < 0 && window.location.href.indexOf('facebook.com') < 0;
  752. if (where) {
  753. return
  754. }
  755. twitterPinLogin();
  756. // 渲染dom
  757. initParseCard()
  758. showNFTCard()
  759. showNFTGroupIcon()
  760. addEventAction();
  761. checkUserJoinGroup();
  762. renderDom();
  763. checkTwitterTaskState();
  764. initBuyNFT();
  765. addJoinedGroupList();
  766. getSysTheme();
  767. // getTweetAccountGroupInfo( () => {
  768. addGroupTab()
  769. // })
  770. getChromeStorage("popupShowPublishDialog", (res) => {
  771. console.log("popupShowPublishDialog", res);
  772. if (res && res.show) {
  773. setTimeout(() => {
  774. showTwitterPublishDialogHandler({
  775. srcContent: res.srcContent,
  776. postId: res.postId,
  777. copyContent: res.copyContent || ''
  778. });
  779. }, 1500);
  780. chrome.storage.local.remove("popupShowPublishDialog");
  781. }
  782. });
  783. getChromeStorage("userSettings", (res) => {
  784. setTimeout(() => {
  785. addPinedPop();
  786. if (res && !res.isOnToolbar) {
  787. setTimeout(() => {
  788. showPinTips();
  789. chrome.storage.local.remove("userSettings");
  790. }, 800);
  791. }
  792. }, 800);
  793. });
  794. }
  795. function checkHasSliderDeBtn() {
  796. let deBtn = document.getElementById('de-btn');
  797. let deBtn3 = document.getElementById('de-btn3');
  798. if (!deBtn && !deBtn3) {
  799. addSliderNavDeBtn();
  800. }
  801. }
  802. export function facebookReplyTweet(params) {
  803. if (window.location.origin.indexOf('twitter.com')) {
  804. const urlParams = new URLSearchParams(window.location.search);
  805. const actionType = urlParams.get('actionType');
  806. let deReplyParams = urlParams.get('deReplyParams') || '{}';
  807. deReplyParams = JSON.parse(deReplyParams);
  808. if (actionType == 'denetFacebookToTwitterReply') {
  809. if (params.postId == deReplyParams.postId) {
  810. let iframe = document.getElementById(params.postId);
  811. iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_FACEBOOK_REPLY', data: deReplyParams }, '*');
  812. }
  813. }
  814. }
  815. }
  816. export function replyHandle(params) {
  817. let iframe = window.parent.document.getElementById(params.postId);
  818. let replyBtn = iframe.parentNode.parentNode.querySelector('div[data-testid="reply"]') ||
  819. iframe.parentNode.parentNode.parentNode.querySelector('div[data-testid="reply"]');
  820. if (replyBtn) {
  821. replyBtn.click();
  822. }
  823. onReplyDialogOpen(params, iframe);
  824. // 详情页推文底部评论处理
  825. let pathNameArr = window.location.pathname.split('/');
  826. if (pathNameArr.length >= 2 && pathNameArr[pathNameArr.length - 2] == 'status') {
  827. let tweetReply = document.querySelector('div[data-testid="tweetButtonInline"]');
  828. if (tweetReply) {
  829. tweetReply.addEventListener('click', function () {
  830. // 详情页回复按钮点击
  831. Report.reportLog({
  832. pageSource: Report.pageSource.mainPage,
  833. businessType: Report.businessType.buttonClick,
  834. objectType: Report.objectType.replyClickByDetailPage
  835. });
  836. let eleList = tweetReply.parentNode.parentNode.parentNode.parentNode.parentNode.querySelectorAll('span[data-text="true"]');
  837. reportReplyResult(eleList, params, () => {
  838. // iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH', data: {} }, '*');
  839. chrome.runtime.sendMessage({ actionType: "CONTENT_RED_PACKET_REPLY_RASK_FINSH", data: { postId: params.postId } }, () => { })
  840. });
  841. })
  842. }
  843. }
  844. }
  845. export function onTweetReplyClick(params) {
  846. let iframe = window.parent.document.getElementById(params.postId);
  847. let replyBtn = iframe.parentNode.parentNode.querySelector('div[data-testid="reply"]') ||
  848. iframe.parentNode.parentNode.parentNode.querySelector('div[data-testid="reply"]');
  849. if (replyBtn) {
  850. replyBtn.addEventListener('click', () => {
  851. onReplyDialogOpen(params, iframe);
  852. })
  853. }
  854. }
  855. function onReplyDialogOpen(params, iframe) {
  856. setTimeout(() => {
  857. let dialog = document.querySelector('div[role="dialog"]');
  858. let replyBtn;
  859. if (dialog) {
  860. let dialogContent = dialog.querySelector('div[role="dialog"]');
  861. replyBtn = dialog.querySelector('div[data-testid="toolBar"]').querySelector('div[data-testid="tweetButton"]');
  862. if (dialogContent) {
  863. let width = dialogContent.offsetWidth;
  864. let ele = document.createElement('div');
  865. ele.innerText = 'Tag 3 friends to complete the task';
  866. ele.style.cssText = `width: ${width}px; height: 38px; color: #fff; font-weight: 600;
  867. font-size: 16px; display: flex; align-items: center; justify-content: center; background: #1D9BF0;
  868. opacity: 0.8; position: absolute; top: 18px; left: 50%; transform: translateX(-50%); z-index: 1000`;
  869. dialogContent.style.top = '80px';
  870. dialogContent.parentNode.appendChild(ele);
  871. }
  872. } else {
  873. dialog = document.querySelector('main[role="main"]');
  874. if (dialog) {
  875. replyBtn = dialog.querySelector('div[data-testid="tweetButton"]');
  876. }
  877. }
  878. if (dialog && replyBtn) {
  879. replyBtn.addEventListener('click', function () {
  880. // 推文页回复按钮点击
  881. Report.reportLog({
  882. pageSource: Report.pageSource.mainPage,
  883. businessType: Report.businessType.buttonClick,
  884. objectType: Report.objectType.replyClickByTwitterList
  885. });
  886. let eleList = dialog.querySelector('div[contenteditable="true"]').querySelectorAll('span[data-text="true"]');
  887. reportReplyResult(eleList, params, () => {
  888. // 上報完成
  889. // iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH', data: {} }, '*');
  890. chrome.runtime.sendMessage({ actionType: "CONTENT_RED_PACKET_REPLY_RASK_FINSH", data: { postId: params.postId } }, () => { })
  891. })
  892. });
  893. }
  894. }, 1000);
  895. }
  896. const reportReplyResult = throttle(function (eleList, params, cb) {
  897. //未过滤的回复文本
  898. Report.reportLog({
  899. pageSource: Report.pageSource.mainPage,
  900. businessType: Report.businessType.buttonClick,
  901. objectType: Report.objectType.replyInputTextGet
  902. }, {
  903. replyStr: eleList
  904. });
  905. if (eleList && eleList.length) {
  906. let atList = [];
  907. for (let i = 0; i < eleList.length; i++) {
  908. let item = eleList[i];
  909. // 是否有中文
  910. let reg = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/g;
  911. if (item && item.innerText.startsWith('@') && !reg.test(item.innerText)) {
  912. atList.push(item.innerText);
  913. }
  914. }
  915. // 去重过滤文本
  916. atList = Array.from(new Set(atList));
  917. Report.reportLog({
  918. pageSource: Report.pageSource.mainPage,
  919. businessType: Report.businessType.buttonClick,
  920. objectType: Report.objectType.replyFilterTextGet
  921. }, {
  922. replyStr: atList
  923. });
  924. if (atList.length >= 3) {
  925. //真实上报
  926. Report.reportLog({
  927. pageSource: Report.pageSource.mainPage,
  928. businessType: Report.businessType.buttonClick,
  929. objectType: Report.objectType.replyReport
  930. }, {
  931. replyStr: atList
  932. });
  933. fetchAddFinishEvent({
  934. eventType: params.type,
  935. luckdropId: params.taskLuckdropId
  936. }).then(res => {
  937. if (res.code == 0) {
  938. cb && cb();
  939. }
  940. })
  941. }
  942. }
  943. }, 800);
  944. // 根据推特id找到dom,完成任务
  945. export function findTweetByIdDoTask({ tweet_Id = '', follow_names = [] }, task_type = 'like') {
  946. // 1.根据推特ID寻找推文,获取卡片
  947. // 获取所有卡片参数
  948. let card_json_data = parseCard.parseAllDeNetCardParmas()
  949. let result = card_json_data.filter((item) => { return item.tweet_Id == tweet_Id }) || []
  950. if (result.length < 1) {
  951. return
  952. }
  953. result = result[0]
  954. switch (task_type) {
  955. case 'like':
  956. // https://twitter.com/intent/retweet?tweet_id=1525900221628223491
  957. if (result.dom_card) {
  958. result.dom_card.querySelector('div[data-testid=like]').click()
  959. result.dom_card.querySelector('iframe').contentWindow.postMessage({ actionType: 'CONTENT_DONE_TASK', task_type, }, '*');
  960. }
  961. break;
  962. case 'retweet':
  963. if (result.dom_card) {
  964. result.dom_card.querySelector('div[data-testid=retweet]').click()
  965. result.dom_card.querySelector('div[data-testid=retweetConfirm]').click()
  966. }
  967. break
  968. case 'follow':
  969. follow_names.forEach((item) => {
  970. window.open(`https://twitter.com/intent/follow?screen_name=${item}&tweet_Id=${tweet_Id}`)
  971. })
  972. break
  973. }
  974. }
  975. function clickByDataTestId(e, id, callback) {
  976. if (e.target.dataset && e.target.dataset.testid && e.target.dataset.testid == id) {
  977. callback()
  978. } else if (e.target.closest('div[data-testid=' + id + ']')) {
  979. callback()
  980. }
  981. }
  982. // 校验关注推特状态
  983. export function checkTwitterTaskState() {
  984. let task_type = ''
  985. let url = window.location.href
  986. let tweet_Id
  987. let task_data = {
  988. follow_name: ''
  989. }
  990. // 校验当前链接
  991. if (url.includes('https://twitter.com/intent/retweet')) {
  992. task_type = 'retweet'
  993. } else if (url.includes('https://twitter.com/intent/follow')) {
  994. task_type = 'follow'
  995. task_data.follow_name = getQueryString('screen_name')
  996. } else if (url.includes('https://twitter.com/intent/like')) {
  997. task_type = 'like'
  998. } else {
  999. return
  1000. }
  1001. tweet_Id = getQueryString('tweet_id')
  1002. // let root_status
  1003. document.body.addEventListener('click', (e) => {
  1004. // 点击 确认
  1005. clickByDataTestId(e, 'confirmationSheetConfirm', () => {
  1006. chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: true }, () => { })
  1007. })
  1008. // 点击取消
  1009. clickByDataTestId(e, 'confirmationSheetCancel', () => {
  1010. chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: false }, () => { })
  1011. })
  1012. // 点击 蒙层
  1013. if (e.target && e.target.nextSibling && e.target.nextSibling.dataset && e.target.nextSibling.dataset.testid == 'confirmationSheetDialog') {
  1014. chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: false }, () => { })
  1015. }
  1016. }, true)
  1017. let timer = setInterval(() => {
  1018. // 喜欢
  1019. if (document.querySelector('div[data-testid=unlike]') && task_type == 'like') {
  1020. clearInterval(timer)
  1021. chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: true }, () => { })
  1022. }
  1023. // 转推
  1024. if (document.querySelector('div[data-testid=unretweet]') && task_type == 'retweet') {
  1025. clearInterval(timer)
  1026. chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: true }, () => { })
  1027. }
  1028. // 关注
  1029. if (task_type == 'follow') {
  1030. let follow_area = document.querySelector('div[data-testid=placementTracking]')
  1031. if (follow_area && follow_area.querySelectorAll('div')) {
  1032. follow_area = follow_area.querySelectorAll('div')
  1033. clearInterval(timer)
  1034. for (let i in follow_area) {
  1035. if (follow_area[i] && follow_area[i].dataset && follow_area[i].dataset.testid && follow_area[i].dataset.testid.indexOf('unfollow') > 0) {
  1036. chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: true }, () => { })
  1037. break
  1038. }
  1039. }
  1040. }
  1041. }
  1042. }, 1000)
  1043. }
  1044. export function getTweetAuthorByDom(params) {
  1045. let iframe = document.getElementById(params.postId);
  1046. if (!iframe) {
  1047. return;
  1048. }
  1049. let fullNameDom;
  1050. let pathNameArr = window.location.pathname.split('/');
  1051. if (pathNameArr.length >= 2 && pathNameArr[pathNameArr.length - 2] == 'status') {
  1052. fullNameDom = iframe.parentNode.parentNode.parentNode.parentNode.querySelector('a[role=link]');
  1053. } else {
  1054. fullNameDom = iframe.parentNode.parentNode.parentNode.querySelector('a[role=link]');
  1055. }
  1056. if (fullNameDom) {
  1057. let arr = fullNameDom.href.split('/');
  1058. if (arr.length) {
  1059. let fullName = arr[arr.length - 1];
  1060. if (fullName) {
  1061. iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_GET_TWEET_AUTHOR', data: { fullName } }, '*');
  1062. }
  1063. }
  1064. }
  1065. }
  1066. export function doTaskTwitterAPI({ task_data, task_type }) {
  1067. switch (task_type) {
  1068. case 'like':
  1069. TwitterLikeAPI(task_data.tweet_Id)
  1070. break
  1071. case 'retweet':
  1072. TwitterRetweetAPI(task_data.tweet_Id)
  1073. break
  1074. case 'follow':
  1075. task_data.follow_data.forEach((item) => {
  1076. if (item.name && item.twitterUserId) {
  1077. TwitterFollowAPI(item, task_data.tweet_Id)
  1078. }
  1079. })
  1080. break
  1081. }
  1082. }
  1083. export function showJoinDialog(data) {
  1084. let iframe = document.querySelector('#nftProjectId')
  1085. iframe.style.display = 'block'
  1086. iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/group?params=${JSON.stringify(data)}`)
  1087. }
  1088. const TwitterFollowAPI = (item, tweet_Id) => {
  1089. fetch("https://twitter.com/i/api/1.1/friendships/create.json", {
  1090. "headers": {
  1091. "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
  1092. "content-type": "application/x-www-form-urlencoded",
  1093. "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"",
  1094. "sec-ch-ua-mobile": "?0",
  1095. "sec-ch-ua-platform": "\"macOS\"",
  1096. "x-csrf-token": getCookie('ct0'),
  1097. "x-twitter-active-user": "yes",
  1098. "x-twitter-auth-type": "OAuth2Session",
  1099. "x-twitter-client-language": "zh-cn"
  1100. },
  1101. "referrer": "https://twitter.com/home",
  1102. "referrerPolicy": "strict-origin-when-cross-origin",
  1103. "body": "include_profile_interstitial_type=1&include_blocking=1&include_blocked_by=1&include_followed_by=1&include_want_retweets=1&include_mute_edge=1&include_can_dm=1&include_can_media_tag=1&include_ext_has_nft_avatar=1&skip_status=1&user_id=" + item.twitterUserId + "",
  1104. "method": "POST",
  1105. "mode": "cors",
  1106. "credentials": "include"
  1107. }).then(() => {
  1108. let task_data = {
  1109. follow_name: item.name
  1110. }
  1111. chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'follow', task_data, task_done: true }, () => { })
  1112. }).catch(() => {
  1113. chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'follow', task_data, task_done: false }, () => { })
  1114. })
  1115. }
  1116. const TwitterRetweetAPI = (tweet_Id) => {
  1117. fetch("https://twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet", {
  1118. "headers": {
  1119. "accept": "*/*",
  1120. "accept-language": "zh,en;q=0.9,zh-CN;q=0.8",
  1121. "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
  1122. "content-type": "application/json",
  1123. "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"",
  1124. "sec-ch-ua-mobile": "?0",
  1125. "sec-ch-ua-platform": "\"macOS\"",
  1126. "sec-fetch-dest": "empty",
  1127. "sec-fetch-mode": "cors",
  1128. "sec-fetch-site": "same-origin",
  1129. "x-csrf-token": getCookie('ct0'),
  1130. "x-twitter-active-user": "yes",
  1131. "x-twitter-auth-type": "OAuth2Session",
  1132. "x-twitter-client-language": "zh-cn"
  1133. },
  1134. "referrer": "https://twitter.com/home",
  1135. "referrerPolicy": "strict-origin-when-cross-origin",
  1136. "body": "{\"variables\":{\"tweet_id\":\"" + tweet_Id + "\",\"dark_request\":false},\"queryId\":\"ojPdsZsimiJrUGLR1sjUtA\"}",
  1137. "method": "POST",
  1138. "mode": "cors",
  1139. "credentials": "include"
  1140. }).then(() => {
  1141. chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'retweet', task_data: '', task_done: true }, () => { })
  1142. }).catch(() => {
  1143. chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'retweet', task_data: '', task_done: false }, () => { })
  1144. })
  1145. }
  1146. const TwitterLikeAPI = (tweet_Id) => {
  1147. fetch("https://twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet", {
  1148. "headers": {
  1149. "accept": "*/*",
  1150. "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
  1151. "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
  1152. "content-type": "application/json",
  1153. "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\", \"Google Chrome\";v=\"101\"",
  1154. "sec-ch-ua-mobile": "?0",
  1155. "sec-ch-ua-platform": "\"Windows\"",
  1156. "sec-fetch-dest": "empty",
  1157. "sec-fetch-mode": "cors",
  1158. "sec-fetch-site": "same-origin",
  1159. "x-csrf-token": getCookie('ct0'),
  1160. "x-twitter-active-user": "yes",
  1161. "x-twitter-auth-type": "OAuth2Session",
  1162. "x-twitter-client-language": "en"
  1163. },
  1164. "referrer": "https://twitter.com/home",
  1165. "referrerPolicy": "strict-origin-when-cross-origin",
  1166. "body": "{\"variables\":{\"tweet_id\":\"" + tweet_Id + "\"},\"queryId\":\"lI07N6Otwv1PhnEgXILM7A\"}",
  1167. "method": "POST",
  1168. "mode": "cors",
  1169. "credentials": "include"
  1170. }).then(() => {
  1171. chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'like', task_data: '', task_done: true }, () => { })
  1172. }).catch(() => {
  1173. chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'like', task_data: '', task_done: false }, () => { })
  1174. })
  1175. }
  1176. let click_old_time = new Date().getTime()
  1177. export const showTwitterPost = (data) => {
  1178. let click_new_time = new Date().getTime()
  1179. if ((click_new_time - click_old_time) < 3000) {
  1180. return
  1181. }
  1182. click_old_time = click_new_time
  1183. let bigBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
  1184. if (bigBtn) {
  1185. bigBtn.click();
  1186. } else {
  1187. let smallBtn = document.querySelector('a[href="/compose/tweet"]')
  1188. smallBtn && smallBtn.click();
  1189. }
  1190. content_get_nft_post_pre({
  1191. groupId: data.groupId
  1192. })
  1193. setGroupTabSelfStyle({
  1194. groupColor: 'rgb(83, 100, 113)',
  1195. groupFontWeight: '500',
  1196. lineDisplay: 'none'
  1197. });
  1198. // addPublishTipsIframe({ type: 'nft' })
  1199. }
  1200. export function publishNFTTweetEvent({ groupId, postId, srcContent }) {
  1201. setTimeout(() => {
  1202. let publishTweetBtn;
  1203. let dialog = document.querySelector('div[role="dialog"]');
  1204. if (dialog) {
  1205. publishTweetBtn = dialog.querySelector('div[data-testid="tweetButton"]');
  1206. } else {
  1207. let domMain = document.querySelector('main[role="main"]');
  1208. publishTweetBtn = domMain && domMain.querySelector('div[data-testid="tweetButton"]');
  1209. }
  1210. publishTweetBtn && publishTweetBtn.addEventListener('click', function () {
  1211. // 获取文案上报
  1212. let inputEle = document.querySelector('div[contenteditable="true"]');
  1213. let textContent = inputEle.innerText
  1214. let arr = srcContent.split(' ') || []
  1215. let text_content_arr = textContent.split(' ') || []
  1216. arr.forEach((item) => {
  1217. if (textContent.includes(item)) {
  1218. textContent = textContent.replaceAll(item, '')
  1219. }
  1220. })
  1221. text_content_arr.forEach((item) => {
  1222. if (item.includes('#DNFT') || item.includes('⬇️')) {
  1223. textContent = textContent.replaceAll(item, '')
  1224. }
  1225. })
  1226. textContent = textContent.replaceAll('#DNFT', '')
  1227. textContent = textContent.replaceAll('⬇️', '')
  1228. let formData = {
  1229. groupId,
  1230. textContent
  1231. }
  1232. let params = {
  1233. postBizData: JSON.stringify(formData),
  1234. postSrc: 1, //1 twitter
  1235. postType: 2, //2 nft
  1236. postId
  1237. }
  1238. chrome.runtime.sendMessage({
  1239. actionType: "CONTENT_NFT_TXT_PUBLISH",
  1240. data: params
  1241. }, () => { });
  1242. jumpTwitterDetailByAlert()
  1243. setTimeout(() => {
  1244. setGroupTabSelfStyle({
  1245. groupColor: 'rgb(83, 100, 113)',
  1246. groupFontWeight: '500',
  1247. lineDisplay: 'none'
  1248. });
  1249. chrome.runtime.sendMessage({
  1250. actionType: "SWITCH_GROUP_BANNER_STATUS",
  1251. data: { type: 'arrow' }
  1252. }, () => { });
  1253. }, 2000);
  1254. });
  1255. }, 800)
  1256. }
  1257. const content_get_nft_post_pre = (data) => {
  1258. chrome.runtime.sendMessage({
  1259. actionType: "CONTENT_GET_TWITTER_NFT_POST_PRE",
  1260. data
  1261. }, () => { });
  1262. }
  1263. let tweet_nft_content = {}
  1264. export const setTwitterTextarea = (params) => {
  1265. tweet_nft_content = params
  1266. let inputEle = document.querySelector('div[contenteditable="true"]');
  1267. if (inputEle) {
  1268. inputEle.focus();
  1269. document.execCommand("insertText", false, '');
  1270. setTimeout(() => {
  1271. document.execCommand("insertText", false, params.srcContent);
  1272. }, 1000);
  1273. publishNFTTweetEvent(params)
  1274. }
  1275. }
  1276. const initGroupTip = () => {
  1277. let arr = window.location.pathname.split('/') || []
  1278. if (arr.length >= 2) {
  1279. let twitterAccount = arr[1]
  1280. let iframe_banner = document.querySelector('#denet_group_tip')
  1281. if (iframe_banner) {
  1282. if (twitterAccount != getQueryStringByUrl(iframe_banner.src, 'twitterAccount')) {
  1283. iframe_banner.style.display = 'none'
  1284. iframe_banner.src = chrome.runtime.getURL(`/iframe/group-card.html?twitterAccount=${twitterAccount}`)
  1285. }
  1286. return
  1287. }
  1288. try {
  1289. let dom = document.querySelector('div[data-testid="ScrollSnap-SwipeableList"]').closest('nav')
  1290. let iframe = document.createElement('iframe')
  1291. iframe.id = 'denet_group_tip'
  1292. iframe.style.cssText = 'border: medium none; display:none; width:100%; height:100px;'
  1293. iframe.src = chrome.runtime.getURL(`/iframe/group-card.html?twitterAccount=${twitterAccount}`)
  1294. if (dom && !dom.parentNode.children[0].querySelector('iframe')) {
  1295. dom.parentNode.children[0].appendChild(iframe)
  1296. }
  1297. } catch (error) {
  1298. }
  1299. }
  1300. }
  1301. export const showGroupTip = () => {
  1302. let dom_denet_group_tip = document.querySelector('#denet_group_tip')
  1303. dom_denet_group_tip.style.display = 'block'
  1304. }
  1305. export const hideBuyNFT = () => {
  1306. let iframe = document.querySelector('#nftProjectId')
  1307. iframe.style.display = 'none'
  1308. iframe.src = ''
  1309. }
  1310. export const showBuyNFT = ({ nft_project_Id }) => {
  1311. if (!nft_project_Id) {
  1312. return
  1313. }
  1314. let iframe = document.querySelector('#nftProjectId')
  1315. iframe.style.display = 'block'
  1316. iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html?nftProjectId=${nft_project_Id}`)
  1317. }
  1318. const initBuyNFT = () => {
  1319. let url = chrome.runtime.getURL(`/iframe/buy-nft.html`)
  1320. let id = `nftProjectId`
  1321. createNFTIframe({ url, id })
  1322. }
  1323. export const showNFTCard = () => {
  1324. let urlInfo = new URL(window.location.href)
  1325. let isTwitter = urlInfo.hostname === 'twitter.com'
  1326. let userElem = document.querySelector('div[data-testid="UserName"]');
  1327. let sideElem = document.querySelector('div[data-testid="sidebarColumn"]')
  1328. let tabIndex = sideElem && sideElem.querySelector('div[tabindex="0"]');
  1329. let isAppend = document.querySelector('div[id="de-nft-node"]');
  1330. let where = isTwitter && userElem && tabIndex;
  1331. if (where) {
  1332. let iframe = document.createElement('iframe');
  1333. iframe.src = chrome.runtime.getURL(`/iframe/nft-card.html`)
  1334. iframe.style.cssText = 'border:medium none; width:100%; height:290px;';
  1335. let nftElement = document.createElement('div');
  1336. nftElement.id = 'de-nft-node';
  1337. nftElement.innerHTML = `
  1338. ${iframe.outerHTML}
  1339. <style>
  1340. #de-nft-node {height:290px; margin-bottom:17px; display:none;}
  1341. </style>
  1342. `;
  1343. if (tabIndex && tabIndex.firstChild && tabIndex.firstChild.childNodes && !isAppend) {
  1344. tabIndex.firstChild.insertBefore(nftElement, tabIndex.firstChild.childNodes[2]);
  1345. }
  1346. }
  1347. }
  1348. export const showNFTSale = () => {
  1349. document.querySelector('div[id="de-nft-node"]').style.display = 'block';
  1350. }
  1351. export const addEventAction = () => {
  1352. let urlInfo = new URL(window.location.href)
  1353. let isTwitter = urlInfo.hostname === 'twitter.com'
  1354. // 监听发推按钮
  1355. let bigBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
  1356. let smallBtn = document.querySelector('a[href="/compose/tweet"]');
  1357. let addBtn = document.querySelector('div[data-testid="addButton"]');
  1358. elemAddEventListener(bigBtn, 'click', () => { queue_num = 3 })
  1359. elemAddEventListener(smallBtn, 'click', () => { queue_num = 3 })
  1360. elemAddEventListener(addBtn, 'click', () => { queue_num = 3 })
  1361. // 页面滚动
  1362. if (isTwitter) {
  1363. // 首页
  1364. if (urlInfo.pathname === '/home') {
  1365. window.addEventListener('scroll', () => {
  1366. hideNFTGroupList()
  1367. })
  1368. }
  1369. }
  1370. }
  1371. export const appendPopupPage = (params = {}) => {
  1372. let { path = '' } = params;
  1373. let iframe = document.createElement('iframe');
  1374. iframe.id = 'de-popup-page';
  1375. iframe.src = chrome.runtime.getURL('/iframe/popup-page.html') + `#${path}`;
  1376. iframe.style.cssText = `border: medium none; width: 375px;
  1377. height: 650px;position: fixed; right: 16px; top: 16px;background: #FFFFFF;border: 0.5px solid #919191;box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.2);box-sizing: border-box;z-index: 90000;
  1378. animation-duration: 0.5s !important;
  1379. animation-timing-function: ease-in-out !important;
  1380. animation-fill-mode: forwards !important;
  1381. transition: all 1s ease 0s !important;right: -385px;transform: translateX(385px);`
  1382. let iframeContent = document.getElementById('de-popup-page');
  1383. let overlayDom = document.createElement('div');
  1384. overlayDom.id = 'de-popup-overlay';
  1385. overlayDom.style.cssText = `position: fixed;z-index: 88888;top: 0;
  1386. left: 0;width: 100%;height: 100%;opacity: 0;display: none`;
  1387. let overlay = document.getElementById('de-popup-overlay');
  1388. let body = document.querySelector('body');
  1389. if (!iframeContent && body) {
  1390. document.querySelector('body').appendChild(iframe);
  1391. if (!overlay) {
  1392. document.querySelector('body').appendChild(overlayDom);
  1393. overlayDom.addEventListener('click', function () {
  1394. hidePopupPage();
  1395. })
  1396. } else {
  1397. overlay.addEventListener('click', function () {
  1398. hidePopupPage();
  1399. })
  1400. }
  1401. }
  1402. }
  1403. let showPopupPageFrom = '';
  1404. export const showPopupPage = (params = {}) => {
  1405. let { path = '', from, showJoinGroupFinish = false } = params;
  1406. showPopupPageFrom = from;
  1407. hidePinTips();
  1408. hideNoticeBindTweet();
  1409. let iframe = document.getElementById('de-popup-page');
  1410. if (!iframe) {
  1411. appendPopupPage();
  1412. iframe = document.getElementById('de-popup-page');
  1413. }
  1414. if (iframe) {
  1415. if (path) {
  1416. iframe.src = chrome.runtime.getURL('/iframe/popup-page.html') + `#${path}`;
  1417. }
  1418. iframe.style.transform = 'translateX(-' + 395 + 'px)';
  1419. chrome.runtime.sendMessage({
  1420. actionType: "CONTENT_POPUP_PAGE_SHOW",
  1421. data: {
  1422. path,
  1423. showJoinGroupFinish,
  1424. }
  1425. }, () => { });
  1426. chrome.runtime.sendMessage({
  1427. actionType: "CONTENT_SET_POPUP_CONFIG",
  1428. data: {
  1429. popup: ''
  1430. }
  1431. }, () => { });
  1432. let overlay = document.getElementById('de-popup-overlay');
  1433. overlay.style.display = 'block';
  1434. let htmlDom = document.querySelector('html');
  1435. if (htmlDom) {
  1436. htmlDom.style.overflowY = 'hidden';
  1437. }
  1438. }
  1439. }
  1440. export const hidePopupPage = () => {
  1441. let iframe = document.getElementById('de-popup-page');
  1442. if (iframe) {
  1443. iframe.style.transform = 'translateX(' + 385 + 'px)';
  1444. let overlay = document.getElementById('de-popup-overlay');
  1445. overlay.style.display = 'none';
  1446. let htmlDom = document.querySelector('html');
  1447. if (htmlDom) {
  1448. htmlDom.style.overflowY = 'auto';
  1449. }
  1450. chrome.runtime.sendMessage({
  1451. actionType: "CONTENT_SET_POPUP_CONFIG",
  1452. data: {
  1453. popup: 'popup.html'
  1454. }
  1455. }, () => { });
  1456. if (showPopupPageFrom == 'BUY_NFT_FINISH') {
  1457. chrome.runtime.sendMessage({
  1458. actionType: "CONTENT_GET_PINED",
  1459. data: {}
  1460. }, () => { });
  1461. showPopupPageFrom = '';
  1462. }
  1463. }
  1464. }
  1465. export const tiggerInjectPopupPage = () => {
  1466. let iframeContent = document.getElementById('de-popup-page');
  1467. if (iframeContent) {
  1468. hidePinTips();
  1469. hideNoticeBindTweet();
  1470. let { transform = '' } = iframeContent.style;
  1471. if (transform == 'translateX(385px)' || !transform) {
  1472. showPopupPage();
  1473. } else {
  1474. hidePopupPage();
  1475. }
  1476. } else {
  1477. appendPopupPage();
  1478. setTimeout(() => {
  1479. let iframe = document.getElementById('de-popup-page');
  1480. let { transform = '' } = iframe.style;
  1481. if (transform == 'translateX(385px)' || !transform) {
  1482. showPopupPage();
  1483. } else {
  1484. hidePopupPage();
  1485. }
  1486. }, 300)
  1487. }
  1488. }
  1489. const onBodyClick = () => {
  1490. if (window.location.href.indexOf('api.twitter.com') < 0) {
  1491. document.querySelector('body').addEventListener('click', function () {
  1492. console.log('click')
  1493. // hidePopupPage();
  1494. })
  1495. }
  1496. }
  1497. export const setPopupConfByPopupPage = () => {
  1498. let iframe = document.getElementById('de-popup-page');
  1499. if (iframe) {
  1500. let { transform = '' } = iframe.style;
  1501. if (transform && transform == 'translateX(-395px)') {
  1502. chrome.runtime.sendMessage({
  1503. actionType: "CONTENT_SET_POPUP_CONFIG",
  1504. data: {
  1505. popup: ''
  1506. }
  1507. }, () => { });
  1508. } else {
  1509. chrome.runtime.sendMessage({
  1510. actionType: "CONTENT_SET_POPUP_CONFIG",
  1511. data: {
  1512. popup: 'popup.html'
  1513. }
  1514. }, () => { });
  1515. }
  1516. } else {
  1517. chrome.runtime.sendMessage({
  1518. actionType: "CONTENT_SET_POPUP_CONFIG",
  1519. data: {
  1520. popup: 'popup.html'
  1521. }
  1522. }, () => { });
  1523. }
  1524. }
  1525. /**
  1526. *
  1527. * Group Tab List Start
  1528. */
  1529. const addGroupTab = () => {
  1530. let illegalPages = ['notifications', 'explore', 'followers', 'following'];
  1531. let page = window.location.pathname.split('/');
  1532. if (page && page.length) {
  1533. if (illegalPages.indexOf(page[page.length - 1]) > -1) {
  1534. return;
  1535. }
  1536. }
  1537. main();
  1538. function main() {
  1539. let tabListDom = document.querySelector('div[role="tablist"]');
  1540. let groupItemTab = document.querySelector('#de-nav-tab-group');
  1541. let groupIcon = document.createElement('img');
  1542. groupIcon.id = 'de-group-tab-icon'
  1543. groupIcon.src = require("@/assets/img/icon-group-tab-item.png");
  1544. groupIcon.style.cssText = 'width:20px;height: 20px;margin-right:4px;';
  1545. let divNode = document.createElement('div');
  1546. divNode.style.cssText = 'display: flex; align-items: center';
  1547. divNode.appendChild(groupIcon);
  1548. divNode.appendChild(document.createTextNode('Group'));
  1549. if (tabListDom && !groupItemTab) {
  1550. let lineDom = document.createElement('div');
  1551. lineDom.id = 'de-tab-line';
  1552. lineDom.style.cssText = `border-radius: 9999px;
  1553. position: absolute;
  1554. bottom: 0px;
  1555. min-width: 56px;
  1556. align-self: center;
  1557. height: 4px;
  1558. background-color: rgb(29, 155, 240);
  1559. display: none`;
  1560. let groupTab = document.createElement('div');
  1561. groupTab.id = 'de-nav-tab-group';
  1562. groupTab.style.cssText = `z-index: 1;
  1563. position: relative;
  1564. display: flex;
  1565. min-width: 56px;
  1566. -webkit-box-pack: center;
  1567. justify-content: center;
  1568. -webkit-box-align: center;
  1569. align-items: center;
  1570. text-align: center;
  1571. padding: 0px 16px;
  1572. color: rgb(83, 100, 113);
  1573. font-weight: 700;
  1574. height: 53px;
  1575. cursor: pointer;
  1576. font: 500 15px / 20px TwitterChirp, -apple-system, "system-ui", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;`;
  1577. groupTab.appendChild(divNode);
  1578. groupTab.appendChild(lineDom);
  1579. tabListDom.appendChild(groupTab);
  1580. groupTab.addEventListener('mouseenter', function () {
  1581. groupTab.style.background = 'rgba(15, 20, 25, 0.1)'
  1582. });
  1583. groupTab.addEventListener('mouseleave', function () {
  1584. groupTab.style.background = 'none'
  1585. });
  1586. setTimeout(() => {
  1587. let count = 0;
  1588. hiddenMaskWeb3Tab(count);
  1589. }, 2000)
  1590. addGroupTabEventListener({ groupTab });
  1591. }
  1592. addTweetTabEventListener({
  1593. tabListDom
  1594. });
  1595. addTabGroupContent(() => {
  1596. checkNeedSelectGroupTab();
  1597. });
  1598. }
  1599. }
  1600. const hiddenMaskWeb3Tab = (count) => {
  1601. setTimeout(() => {
  1602. count++;
  1603. if (count < 6) {
  1604. let tab = getMaskWeb3Tab();
  1605. if (tab) {
  1606. tab.style.display = 'none'
  1607. } else {
  1608. hiddenMaskWeb3Tab(count);
  1609. }
  1610. }
  1611. }, 1000);
  1612. }
  1613. /**
  1614. * 跳转到个人主页 检查是否需要选中 Group tab
  1615. */
  1616. const checkNeedSelectGroupTab = () => {
  1617. if (window.location.pathname != '/home') {
  1618. getChromeStorage('groupTabData', (res) => {
  1619. if (res && res.deTabVal == 'deGroupTab') {
  1620. chrome.storage.local.remove("groupTabData");
  1621. setTimeout(() => {
  1622. selectGroupTab();
  1623. }, 300)
  1624. }
  1625. })
  1626. }
  1627. }
  1628. /** 选中 Group tab */
  1629. export const selectGroupTab = () => {
  1630. let groupTab = document.querySelector('#de-nav-tab-group');
  1631. if (groupTab) {
  1632. groupTab.click();
  1633. }
  1634. };
  1635. /**
  1636. *
  1637. * Group tab点击事件监听
  1638. */
  1639. const addGroupTabEventListener = (params) => {
  1640. let { groupTab } = params;
  1641. groupTab.addEventListener('click', function () {
  1642. let groupColor = systemInfo.theme == 'light' ? 'rgb(15, 20, 25)' : '#fff';
  1643. setGroupTabSelfStyle({
  1644. groupColor: groupColor,
  1645. groupFontWeight: '700',
  1646. lineDisplay: 'block'
  1647. });
  1648. setTweetActiveTabStyle({
  1649. color: 'rgb(83, 100, 113)',
  1650. display: 'none'
  1651. });
  1652. setTabContentStyle({
  1653. tweetTabContentDisply: 'none',
  1654. iframeContentDisplay: 'block'
  1655. });
  1656. refreshTabGroup();
  1657. window.addEventListener('scroll', addPageScrollEvent);
  1658. let tipsDom = document.querySelector('#denet_group_tip');
  1659. if (tipsDom) {
  1660. chrome.runtime.sendMessage({
  1661. actionType: "SWITCH_GROUP_BANNER_STATUS",
  1662. data: { type: 'btn' }
  1663. }, () => { });
  1664. } else {
  1665. onShowGroupBanner();
  1666. }
  1667. })
  1668. }
  1669. const onShowGroupBanner = () => {
  1670. chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
  1671. switch (req.actionType) {
  1672. case 'IFRAME_SHOW_GROUP_TIP':
  1673. chrome.runtime.sendMessage({
  1674. actionType: "SWITCH_GROUP_BANNER_STATUS",
  1675. data: { type: 'btn' }
  1676. }, () => { });
  1677. break
  1678. }
  1679. })
  1680. }
  1681. const addPageScrollEvent = () => {
  1682. let wrapperDom = document.querySelector('html');
  1683. let contentDom = document.querySelector('main[role="main"]');
  1684. let data = {
  1685. wrapperHeight: wrapperDom.offsetHeight,
  1686. wrapperScrollTop: wrapperDom.scrollTop,
  1687. contentHeight: contentDom.offsetHeight
  1688. }
  1689. chrome.runtime.sendMessage({
  1690. actionType: "CONTENT_GROUP_LIST_SCROLL",
  1691. data: data
  1692. }, () => { });
  1693. };
  1694. /**
  1695. *
  1696. * twitter tab点击事件监听
  1697. */
  1698. const addTweetTabEventListener = (params) => {
  1699. let { tabListDom } = params;
  1700. let groupItemTab = document.querySelector('#de-nav-tab-group');
  1701. if (tabListDom && groupItemTab) {
  1702. // 监听twitter tab点击事件
  1703. let tweetTabItem = tabListDom.querySelectorAll('div[role="presentation"]');
  1704. if (tweetTabItem.length) {
  1705. for (let i = 0; i < tweetTabItem.length; i++) {
  1706. let item = tweetTabItem[i];
  1707. item.addEventListener('click', function () {
  1708. window.removeEventListener('scroll', addPageScrollEvent);
  1709. setGroupTabSelfStyle({
  1710. groupColor: 'rgb(83, 100, 113)',
  1711. groupFontWeight: '500',
  1712. lineDisplay: 'none'
  1713. });
  1714. setTabContentStyle({
  1715. tweetTabContentDisply: 'block',
  1716. iframeContentDisplay: 'none'
  1717. });
  1718. setTweetActiveTabStyle({
  1719. color: 'rgb(15, 20, 25)',
  1720. display: 'block'
  1721. });
  1722. chrome.runtime.sendMessage({
  1723. actionType: "SWITCH_GROUP_BANNER_STATUS",
  1724. data: { type: 'arrow' }
  1725. }, () => { });
  1726. })
  1727. }
  1728. }
  1729. }
  1730. }
  1731. /**
  1732. * 设置 Group Tab 样式
  1733. * */
  1734. const setGroupTabSelfStyle = (params = {}) => {
  1735. let { groupColor, groupFontWeight, lineDisplay } = params;
  1736. let groupTab = document.querySelector('#de-nav-tab-group');
  1737. groupTab.style.color = groupColor;
  1738. groupTab.style.fontWeight = groupFontWeight;
  1739. let lineDom = groupTab.querySelector('#de-tab-line');
  1740. if (lineDom) {
  1741. lineDom.style.display = lineDisplay;
  1742. }
  1743. };
  1744. /**
  1745. * 切换到 Group tab时 刷新列表
  1746. */
  1747. export const refreshTabGroup = () => {
  1748. chrome.runtime.sendMessage({
  1749. actionType: "CONTENT_REFRESH_TAB_GROUP_LIST",
  1750. data: {}
  1751. }, () => { });
  1752. }
  1753. /**
  1754. *
  1755. * tab选中时设置 激活 的字体样式和选中条
  1756. */
  1757. const setTweetActiveTabStyle = (params) => {
  1758. let { color, display } = params || {};
  1759. let tweetActiveTab = document.querySelector('a[aria-selected="true"]').querySelector('div');
  1760. tweetActiveTab.style.color = color;
  1761. let tweetTabLine = tweetActiveTab.querySelector('div');
  1762. if (tweetTabLine) {
  1763. tweetTabLine.style.display = display;
  1764. }
  1765. }
  1766. /**
  1767. *
  1768. * 设置 tab 切换时 tab内容的样式(显示隐藏)
  1769. */
  1770. const setTabContentStyle = (params) => {
  1771. let { tweetTabContentDisply, iframeContentDisplay } = params;
  1772. let tweetTabContent = getTweetTabContent();
  1773. if (tweetTabContent) {
  1774. if (tweetTabContentDisply == 'block') {
  1775. let { visibility } = tweetTabContent.style;
  1776. if (visibility == 'hidden') {
  1777. tweetTabContent.style.visibility = 'visible';
  1778. tweetTabContent.style.height = 'auto';
  1779. tweetTabContent.style.overflow = 'auto';
  1780. }
  1781. } else {
  1782. tweetTabContent.style.visibility = 'hidden';
  1783. tweetTabContent.style.height = '0px';
  1784. tweetTabContent.style.overflow = 'hidden';
  1785. }
  1786. }
  1787. let iframeContent = document.getElementById('de-tab-group-content');
  1788. if (!iframeContent) {
  1789. addTabGroupContent();
  1790. }
  1791. setTimeout(() => {
  1792. iframeContent = document.getElementById('de-tab-group-content');
  1793. if (iframeContent) {
  1794. iframeContent.style.display = iframeContentDisplay;
  1795. }
  1796. })
  1797. };
  1798. /**
  1799. *
  1800. * 获取 twitter tab 下的内容
  1801. */
  1802. const getTweetTabContent = () => {
  1803. let tweetTabContent = document.querySelector('[data-testid="primaryColumn"] [role="navigation"] + * > div[aria-label]:not([role="progressbar"])') || document.querySelector('div[data-testid="emptyState"]');
  1804. return tweetTabContent;
  1805. }
  1806. /**
  1807. * 注入 Group List 内容
  1808. */
  1809. const addTabGroupContent = (cb) => {
  1810. let params = {
  1811. windowLocation: window.location
  1812. }
  1813. let iframe = document.createElement('iframe');
  1814. iframe.id = 'de-tab-group-content';
  1815. iframe.src = chrome.runtime.getURL('/iframe/tab-group.html') + `?params=${JSON.stringify(params)}`;
  1816. iframe.style.cssText = `border: medium none; height: 500px;display: none`
  1817. let iframeContent = document.getElementById('de-tab-group-content');
  1818. let tweetTabContent = getTweetTabContent();
  1819. if (!iframeContent) {
  1820. if (tweetTabContent && tweetTabContent.parentElement) {
  1821. tweetTabContent.parentElement.appendChild(iframe);
  1822. cb && cb();
  1823. }
  1824. }
  1825. };
  1826. /**
  1827. *
  1828. * 设置Tab Group Iframe 样式
  1829. */
  1830. export const setTabGroupIframeStyle = (params) => {
  1831. let iframeContent = document.getElementById('de-tab-group-content');
  1832. if (iframeContent) {
  1833. iframeContent.style.height = document.querySelector('html').offsetHeight + 'px';
  1834. }
  1835. }
  1836. /**
  1837. * mask Tab
  1838. *
  1839. */
  1840. const getMaskWeb3Tab = () => {
  1841. let tab = document.querySelector('div[data-testid="ScrollSnap-nextButtonWrapper"] + span');
  1842. return tab;
  1843. }
  1844. export const pageJumpHandler = (params) => {
  1845. let { url } = params
  1846. if (url) {
  1847. window.open(url)
  1848. }
  1849. }
  1850. export const getTweetProfileNavTop = (params) => {
  1851. let top = document.querySelector('div[role="tablist"]').closest('nav').getBoundingClientRect().top;
  1852. chrome.runtime.sendMessage({
  1853. actionType: "CONTENT_SEND_GROUP_NAV_TOP", data: {
  1854. top,
  1855. scrollTop: params.scrollTop
  1856. }
  1857. }, () => { })
  1858. }
  1859. /**
  1860. *
  1861. * Group Tab List End
  1862. *
  1863. */
  1864. export const loginSuccessHandle = () => {
  1865. // 检查是否漏出group图标
  1866. checkUserJoinGroup(() => {
  1867. showNFTGroupIcon()
  1868. addEventAction()
  1869. addJoinedGroupList();
  1870. })
  1871. }
  1872. export const setGroupInfo = (params = {}) => {
  1873. console.log('params', params)
  1874. tweetAccountBindGroupInfo.groupInfo = params;
  1875. if (!params.nftGroupId) {
  1876. let groupTab = document.querySelector('#de-nav-tab-group');
  1877. if (groupTab) {
  1878. groupTab.style.display = 'none';
  1879. } else {
  1880. setTimeout(() => {
  1881. groupTab = document.querySelector('#de-nav-tab-group');
  1882. if (groupTab) {
  1883. groupTab.style.display = 'none';
  1884. }
  1885. }, 500)
  1886. }
  1887. }
  1888. }
  1889. const getSysTheme = () => {
  1890. const themeMedia = window.matchMedia("(prefers-color-scheme: light)");
  1891. if (themeMedia.matches) {
  1892. systemInfo.theme = 'light'
  1893. } else {
  1894. systemInfo.theme = 'dark'
  1895. }
  1896. themeMedia.addListener(e => {
  1897. addGroupTab()
  1898. if (e.matches) {
  1899. systemInfo.theme = 'light'
  1900. } else {
  1901. systemInfo.theme = 'dark'
  1902. }
  1903. });
  1904. }