瀏覽代碼

merge 1.1.7.4

jihuaqiang 2 年之前
父節點
當前提交
43c64d32a3
共有 35 個文件被更改,包括 1653 次插入976 次删除
  1. 9 0
      src/assets/subject/004-back-head-top.svg
  2. 2 0
      src/assets/svg/icon-gold-box-close.svg
  3. 3 0
      src/assets/svg/icon-loading-gray2.svg
  4. 3 2
      src/denet/content/doTask.js
  5. 29 0
      src/denet/content/getData.js
  6. 4 2
      src/denet/content/index.js
  7. 8 8
      src/entry/background.js
  8. 119 82
      src/entry/content.js
  9. 3 2
      src/iframe/ach-cashier.js
  10. 2 1
      src/iframe/tool-box-buy-nft.js
  11. 3 2
      src/iframe/tool-box-guide.js
  12. 3 1
      src/iframe/tool-box.js
  13. 3 0
      src/iframe/treasure-hunt.js
  14. 17 16
      src/logic/background/twitter.js
  15. 3 3
      src/logic/content/ParseCard.js
  16. 37 33
      src/logic/content/help/doTask.js
  17. 33 0
      src/logic/content/help/getData.js
  18. 182 76
      src/logic/content/twitter.js
  19. 2 2
      src/manifest.json
  20. 8 0
      src/uilts/help.js
  21. 3 0
      src/uilts/messageCenter/iframe/messageEnum.js
  22. 39 0
      src/view/components/loading.vue
  23. 24 14
      src/view/iframe/publish/components/get-more.vue
  24. 61 78
      src/view/iframe/red-packet/luck-draw.vue
  25. 56 75
      src/view/iframe/red-packet/red-packet.vue
  26. 65 143
      src/view/iframe/treasure-hunt/all-receive-list.vue
  27. 8 8
      src/view/iframe/treasure-hunt/components/boxs.vue
  28. 17 4
      src/view/iframe/treasure-hunt/components/btn.vue
  29. 1 0
      src/view/iframe/treasure-hunt/components/carousel.vue
  30. 300 265
      src/view/iframe/treasure-hunt/components/invite-friends.vue
  31. 224 0
      src/view/iframe/treasure-hunt/components/receive-list.vue
  32. 140 15
      src/view/iframe/treasure-hunt/cover.vue
  33. 72 23
      src/view/iframe/treasure-hunt/index.vue
  34. 2 1
      src/view/iframe/treasure-hunt/invite.vue
  35. 168 120
      src/view/iframe/treasure-hunt/result.vue

+ 9 - 0
src/assets/subject/004-back-head-top.svg

@@ -0,0 +1,9 @@
+<svg width="375" height="150" viewBox="0 0 375 150" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 0H375V117.057C375 117.057 320.624 150 187.5 150C54.376 150 0 117.057 0 117.057V0Z" fill="url(#paint0_linear_27657_247702)"/>
+<defs>
+<linearGradient id="paint0_linear_27657_247702" x1="187" y1="-2.34963e-09" x2="187.045" y2="150" gradientUnits="userSpaceOnUse">
+<stop offset="0.367196" stop-color="#26180E"/>
+<stop offset="0.953767" stop-color="#51361D"/>
+</linearGradient>
+</defs>
+</svg>

文件差異過大導致無法顯示
+ 2 - 0
src/assets/svg/icon-gold-box-close.svg


+ 3 - 0
src/assets/svg/icon-loading-gray2.svg

@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M19.9992 3.33203V7.49869C17.2553 7.49927 14.5878 8.40267 12.4083 10.0695C10.2287 11.7364 8.65819 14.0741 7.93892 16.722C7.21965 19.3699 7.39163 22.1809 8.42832 24.7214C9.46501 27.2619 11.3088 29.3907 13.6753 30.7795C16.0418 32.1682 18.7995 32.7397 21.5229 32.4058C24.2464 32.0719 26.7844 30.8511 28.7453 28.9318C30.7062 27.0125 31.9811 24.5014 32.3734 21.7857C32.7657 19.07 32.2535 16.3007 30.9158 13.9049L34.5533 11.8737C36.3369 15.0681 37.0198 18.7605 36.4967 22.3815C35.9737 26.0025 34.2737 29.3508 31.659 31.9098C29.0444 34.4688 25.6604 36.0964 22.029 36.5415C18.3976 36.9866 14.7206 36.2245 11.5653 34.3727C8.41006 32.5209 5.95175 29.6823 4.56965 26.2949C3.18755 22.9074 2.95846 19.1593 3.91772 15.6287C4.87698 12.0982 6.97129 8.98135 9.87757 6.75906C12.7839 4.53676 16.3406 3.3325 19.9992 3.33203Z" fill="#E2E2E2"/>
+</svg>

+ 3 - 2
src/denet/content/doTask.js

@@ -45,7 +45,7 @@ const doTask = {
             })
         })
     },
-    follows({ follows }, overTime) {
+    follows({ follow_name, twitterUserId }, overTime) {
         return new Promise((res, rej) => {
             messageCenter.send({
                 info: {
@@ -53,7 +53,8 @@ const doTask = {
                     iframeId //用于告诉父窗口会传消息给哪个iframe
                 },
                 data: {
-                    follows
+                  follow_name,
+                  twitterUserId
                 },
                 overTime,
                 callback: (data) => {

+ 29 - 0
src/denet/content/getData.js

@@ -0,0 +1,29 @@
+import MESSAGE_ENUM from '@/uilts/messageCenter/iframe/messageEnum'
+import messageCenter from '@/uilts/messageCenter/iframe'
+import { getQueryString } from '@/uilts/help'
+const iframeId = getQueryString('iframeId')
+
+const getData = {
+  getUserInfoByName({screen_name}, overTime) {
+    return new Promise((res, rej) => {
+      messageCenter.send({
+          info: {
+              actionType: MESSAGE_ENUM.IFRAME_GET_TWITTER_USER_INFO,
+              iframeId
+          },
+          data: {
+            screen_name
+          },
+          overTime,
+          callback: (data) => {
+              res(data);
+          },
+          failback: (e) => {
+              rej(e)
+          }
+      })
+    })
+  }
+}
+
+export default getData

+ 4 - 2
src/denet/content/index.js

@@ -1,7 +1,9 @@
 import doTask from '@/denet/content/doTask'
 import dom from '@/denet/content/dom'
+import getData from '@/denet/content/getData'
 
 export default {
     doTask,
-    dom
-}
+    dom,
+    getData
+}

+ 8 - 8
src/entry/background.js

@@ -146,10 +146,10 @@ chrome.tabs.onActivated.addListener(function (activeInfo) {
     setPopupConfig(activeInfo);
 })
 
-function thenInstalledMethod() {
+function thenInstalledMethod({ reason }) {
     try {
 
-        onInstalledCreateTab()
+        onInstalledCreateTab({ reason })
         onInstalledUserSet()
         // pingpang
         chrome.alarms.create('PingPong', {
@@ -187,7 +187,7 @@ function onInstalledMethod({ id, previousVersion, reason }) {
             if (!info || !info.appVersionCode) {
                 setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '1' }) })
                 setChromeStorage({ baseInfo: JSON.stringify({ appVersionCode }) })
-                thenInstalledMethod()
+                thenInstalledMethod({ reason })
 
                 // 版本更新了
             } else if (appVersionCode != info.appVersionCode) {
@@ -199,7 +199,7 @@ function onInstalledMethod({ id, previousVersion, reason }) {
                 })
             } else {
                 setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '3' }) })
-                thenInstalledMethod()
+                thenInstalledMethod({ reason })
             }
             console.log('1-appVersionCode', appVersionCode)
             console.log('1-info', info)
@@ -229,9 +229,9 @@ function onMessageMethod(req, sender, sendResponse) {
             return
         }
         if (req.info) {
-            newOnMessageMethod(req, sender, sendResponse)
+            newRuntimeOnMessageMethod(req, sender, sendResponse)
         } else if (req.actionType) {
-            oldOnMessageMethod(req, sender, sendResponse)
+            oldRuntimeOnMessageMethod(req, sender, sendResponse)
         }
         chromeMessageCenter.init(req)
     } catch (error) {
@@ -245,7 +245,7 @@ function onMessageMethod(req, sender, sendResponse) {
 //加载bg.js 执行
 setMessageCount();
 
-const newOnMessageMethod = (req, sender, sendResponse) => {
+const newRuntimeOnMessageMethod = (req, sender, sendResponse) => {
     let { info = {}, data = {} } = req
     switch (info.actionType) {
         case 'CONTENT_TO_BACK_TEST':
@@ -262,7 +262,7 @@ const newOnMessageMethod = (req, sender, sendResponse) => {
     }
 }
 
-const oldOnMessageMethod = (req, sender, sendResponse) => {
+const oldRuntimeOnMessageMethod = (req, sender, sendResponse) => {
     switch (req.actionType) {
         case "POPUP_LOGIN":
             twitterPinLoginToken();

+ 119 - 82
src/entry/content.js

@@ -47,6 +47,7 @@ import {
     openUrlInNewWindow,
     sendAllFacebookShareSuccess,
     sendUserSettingMessageToAllIframe
+    doTaskIframeTwitterAPI
 } from "@/logic/content/twitter.js";
 import denet from '@/denet'
 import { httpBackToContentCallBack } from '@/uilts/chromeExtension.js'
@@ -66,8 +67,8 @@ import {
 } from "@/logic/content/denet.js";
 
 import doTask from '@/logic/content/help/doTask'
+import getData from '@/logic/content/help/getData'
 import chromeMessageCenter from '@/uilts/messageCenter/chrome';
-import { re } from "mathjs";
 
 chrome.storage.onChanged.addListener(changes => {
     initExecuteScript(changes)
@@ -83,91 +84,127 @@ window.onload = () => {
     });
 };
 
+const oldOnMessageMethod = (res) => {
+    switch (res.data.actionType) {
+        case "IFRAME_SHOW_IFREME":
+            showIframeHandler();
+            break;
+        case "IFRAME_HIDE_IFREME":
+            hideIframeHandler();
+            break;
+        case "IFRAME_SHOW_TWITTER_PUBLISH_DIALOG":
+            showTwitterPublishDialogHandler(res.data.publishRes);
+            break;
+        case "IFRAME_RED_PACKET_REPLY_CLICK":
+            replyHandle(res.data.data || {});
+            break;
+        case "IFRAME_RED_PACKET_SHOW_BIND_TWEET_NOTICE":
+            noticeBindTweet(res.data.data || {});
+            break;
+        case "IFRAME_CLOSE_BIND_TWEET":
+            hideNoticeBindTweet();
+            break;
+        case "IFRAME_RED_PACKET_GET_TWEET_AUTHOR":
+            getTweetAuthorByDom(res.data.data || {});
+            break;
+        case "IFRAME_RED_PACKET_CHECK_FACEBOOK_REPLY":
+            facebookReplyTweet(res.data.data || {});
+            break;
+        case "IFRAME_RED_PACKET_ON_TWEET_REPLY_CLICK":
+            onTweetReplyClick(res.data.data || {});
+            break;
+        // case 'IFRAME_TWITTER_API_DO_TASK':
+        //     doTaskTwitterAPI(res.data)
+        //     break
+        // case "IFRAME_DO_TASK":
+        //     findTweetByIdDoTask(res.data.task_data, res.data.task_type)
+        //     break
+        case 'IFREME_TAB_GROUP_SET_IFRAME_HEIGHT':
+            setTabGroupIframeStyle(res.data.data);
+            break
+        case 'IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP':
+            getTweetProfileNavTop(res.data.data);
+            break;
+        case 'IFRAME_PAGE_JUMP':
+            pageJumpHandler(res.data.data);
+            break;
+        case 'IFRAME_GET_EXTENSION_STORGE_DATA':
+            getExtensionStorgeDataForIframe(res.data.data);
+            break;
+
+        case 'IFRAME_API_GET_TWEET_USER_FOLLOW_STATUS':
+            getTweetUserFollowStatus(res.data);
+            break;
+        case 'IFRAME_TWITTER_API_DO_TASK':
+            doTaskIframeTwitterAPI(res.data);
+            break;
+        case 'IFRAME_API_GET_TWEET_USER_INFO_START':
+            let data = JSON.parse(res.data.data);
+
+            TwitterApiUserByScreenName({
+                iframeId: res.data.iframeId,
+                ...data
+            })
+            break;
+
+        case 'GET_CONTENT_BY_TWITTER_ID':
+            sendContentByTwitterID(res.data)
+            break
+    }
+}
+
+const newOnMessageMethod = (res) => {
+    let { info = {}, data = {} } = res.data
+    switch (info.actionType) {
+        case 'IFRAME_DO_TASK_CREATE_TWEET':
+            doTask.TwitterApiCreateTweet({ info, data })
+            break
+        case 'IFRAME_DO_TASK_LIKE':
+            doTask.TwitterLikeAPI({ info, data })
+            break
+        case 'IFRAME_DO_TASK_RETWEET':
+            doTask.TwitterRetweetAPI({ info, data })
+            break
+        case 'IFRAME_DO_TASK_FOLLOWS':
+            doTask.TwitterFollowAPI({ info, data })
+            break
+        case 'IFRAME_GET_TWITTER_USER_INFO':
+            getData.TwitterApiGetUserInfoByName({ info, data })
+            break
+        case 'IFRAME_TWITTER_API_DO_TASK':
+            console.log('IFRAME_TWITTER_API_DO_TASK...',res.data)
+            doTaskTwitterAPI(res.data)
+            break
+        case 'IFRAME_API_GET_TWEET_USER_INFO_REQ':
+            // 从runtime 迁移
+            TwitterApiUserByScreenName(res.data)
+            break;
+        case "POPUP_LOGIN":
+            // iframe请求登录,通过content转发至 background
+            sendIframeLoginToBackground();
+            break
+        case 'OPEN_URL_IN_NEW_WINDOW':
+            openUrlInNewWindow({info, data})
+            break
+        case 'IFRAME_SET_EXTENSION_STORGE_DATA':
+            setExtensionStorgeDataForIframe(res.data);
+            break;
+    }
+}
+
 
 window.onmessage = (res) => {
     if (!res.data) {
         return
     }
-    let { info = {}, data = {} } = res.data
-    if ((res.data.actionType) || (info && info.actionType)) {
-        switch ((info && info.actionType) || res.data.actionType) {
-            case "IFRAME_SHOW_IFREME":
-                showIframeHandler();
-                break;
-            case "IFRAME_HIDE_IFREME":
-                hideIframeHandler();
-                break;
-            case "IFRAME_SHOW_TWITTER_PUBLISH_DIALOG":
-                showTwitterPublishDialogHandler(res.data.publishRes);
-                break;
-            case "IFRAME_RED_PACKET_REPLY_CLICK":
-                replyHandle(res.data || {});
-                break;
-            case "IFRAME_RED_PACKET_SHOW_BIND_TWEET_NOTICE":
-                noticeBindTweet(res.data.data || {});
-                break;
-            case "IFRAME_CLOSE_BIND_TWEET":
-                hideNoticeBindTweet();
-                break;
-            case "IFRAME_RED_PACKET_GET_TWEET_AUTHOR":
-                getTweetAuthorByDom(res.data || {});
-                break;
-            case "IFRAME_RED_PACKET_CHECK_FACEBOOK_REPLY":
-                facebookReplyTweet(res.data || {});
-                break;
-            case "IFRAME_RED_PACKET_ON_TWEET_REPLY_CLICK":
-                onTweetReplyClick(res.data.data || {});
-                break;
-            // case 'IFRAME_TWITTER_API_DO_TASK':
-            //     doTaskTwitterAPI(res.data)
-            //     break
-            // case "IFRAME_DO_TASK":
-            //     findTweetByIdDoTask(res.data.task_data, res.data.task_type)
-            //     break
-            case 'IFREME_TAB_GROUP_SET_IFRAME_HEIGHT':
-                setTabGroupIframeStyle(res.data.data);
-                break
-            case 'IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP':
-                getTweetProfileNavTop(res.data.data);
-                break;
-            case 'IFRAME_PAGE_JUMP':
-                pageJumpHandler(res.data.data);
-                break;
-            case 'IFRAME_GET_EXTENSION_STORGE_DATA':
-                getExtensionStorgeDataForIframe(res.data);
-                break;
-            case 'IFRAME_SET_EXTENSION_STORGE_DATA':
-                setExtensionStorgeDataForIframe(res.data);
-                break;
-            case 'IFRAME_DO_TASK_CREATE_TWEET':
-                doTask.TwitterApiCreateTweet({ info, data })
-                break
-            case 'IFRAME_DO_TASK_LIKE':
-                doTask.TwitterLikeAPI({ info, data })
-                break
-            case 'IFRAME_DO_TASK_RETWEET':
-                doTask.TwitterRetweetAPI({ info, data })
-                break
-            case 'IFRAME_TWITTER_API_DO_TASK':
-                console.log('IFRAME_TWITTER_API_DO_TASK...',res.data)
-                doTaskTwitterAPI(res.data)
-                break
-            case 'IFRAME_API_GET_TWEET_USER_INFO_REQ':
-                // 从runtime 迁移
-                TwitterApiUserByScreenName(res.data)
-                break;
-            case "POPUP_LOGIN":
-                // iframe请求登录,通过content转发至 background
-                sendIframeLoginToBackground();
-                break
-            case 'OPEN_URL_IN_NEW_WINDOW':
-                openUrlInNewWindow({info, data})
-                break
-        }
+    if (res.data.actionType) {
+        oldOnMessageMethod(res)
+    } else if (res.data.info) {
+        newOnMessageMethod(res)
     }
-};
+}
 
-const oldOnMessageMethod = (req, sender, sendResponse) => {
+const oldRuntimeOnMessageMethod = (req, sender, sendResponse) => {
     switch (req.actionType) {
         case 'BG_SHOW_PIN_TIPS':
             showPinTips()
@@ -291,14 +328,14 @@ const oldOnMessageMethod = (req, sender, sendResponse) => {
     }
 }
 
-const newOnMessageMethod = (req, sender, sendResponse) => {
+const newRuntimeOnMessageMethod = (req, sender, sendResponse) => {
 
 }
 chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     if (req.actionType) {
-        oldOnMessageMethod(req, sender, sendResponse)
+        oldRuntimeOnMessageMethod(req, sender, sendResponse)
     } else if (req.info) {
-        newOnMessageMethod(req, sender, sendResponse)
+        newRuntimeOnMessageMethod(req, sender, sendResponse)
         chromeMessageCenter.init(req)
     }
     sendResponse && sendResponse('ok');

+ 3 - 2
src/iframe/ach-cashier.js

@@ -2,5 +2,6 @@ import { createApp } from 'vue'
 import App from '@/view/iframe/ach-pay/cashier.vue'
 
 const app = createApp(App);
-
-app.mount('#app');
+import CoutomSentry from "@/uilts/sentry.js"
+CoutomSentry.initVue(app)
+app.mount('#app');

+ 2 - 1
src/iframe/tool-box-buy-nft.js

@@ -3,6 +3,7 @@ import App from '@/view/iframe/tool-box/buy-nft.vue'
 import AutoLog from '@/log-center/autoLog';
 
 const app = createApp(App);
-
+import CoutomSentry from "@/uilts/sentry.js"
+CoutomSentry.initVue(app)
 app.use(AutoLog);
 app.mount('#app');

+ 3 - 2
src/iframe/tool-box-guide.js

@@ -6,10 +6,11 @@ import "ant-design-vue/dist/antd.css"; // or 'ant-design-vue/dist/antd.less'
 import {message} from "ant-design-vue";
 
 const app = createApp(App);
-
+import CoutomSentry from "@/uilts/sentry.js"
+CoutomSentry.initVue(app)
 app.use(message);
 app.mount('#app');
 
 window.onload= () => {
     document.title = 'DeNet'
-}
+}

+ 3 - 1
src/iframe/tool-box.js

@@ -1,4 +1,6 @@
 import { createApp } from 'vue'
 import App from '@/view/iframe/tool-box/index.vue'
 const app = createApp(App);
-app.mount('#app');
+import CoutomSentry from "@/uilts/sentry.js"
+CoutomSentry.initVue(app)
+app.mount('#app');

+ 3 - 0
src/iframe/treasure-hunt.js

@@ -1,6 +1,9 @@
 import { createApp } from 'vue'
 import App from '@/view/iframe/test/index.vue'
 import AutoLog from '@/log-center/autoLog';
+import CoutomSentry from "@/uilts/sentry.js"
+
 const app = createApp(App);
+CoutomSentry.initVue(app)
 app.use(AutoLog)
 app.mount('#app');

+ 17 - 16
src/logic/background/twitter.js

@@ -228,7 +228,7 @@ export function onInstalledMid(cb) {
             // 没有cookie
             if (res_arr && res_arr.length) {
                 setChromeStorage({ mid: JSON.stringify(res_arr[0]) }, () => {
-                  cb && cb()
+                    cb && cb()
                 })
             } else {
                 let _params = {
@@ -236,7 +236,7 @@ export function onInstalledMid(cb) {
                 }
                 setChromeCookie(LANDING_PAGE, { 'mid': _params.mid })
                 setChromeStorage({ mid: JSON.stringify(_params) }, () => {
-                  cb && cb()
+                    cb && cb()
                 })
             }
         })
@@ -333,23 +333,24 @@ function sendActivetabMessage(message = {}) {
  * 安装后打开新标签页
  */
 
-export function onInstalledCreateTab() {
+export function onInstalledCreateTab({ reason }) {
     try {
         getChromeCookie(LANDING_PAGE_JUMP_INFO, (res = {}) => {
             onInstalledMid(() => {
-              setTimeout(() => {
-                  if (!res) {
-                      res = {}
-                  }
-                  // 安装成功埋点
-                  Report.reportLog({
-                      objectType: Report.objectType.chrome_extension_installed,
-                      funcName: 'onInstalledCreateTab',
-                      postId: res.postId || '',
-                      shareLinkId: res.shareLinkId || '',
-                      'channel-name': res.channelName
-                  })
-              }, 5000)
+                setTimeout(() => {
+                    if (!res) {
+                        res = {}
+                    }
+                    // 安装成功埋点
+                    Report.reportLog({
+                        objectType: Report.objectType.chrome_extension_installed,
+                        funcName: 'onInstalledCreateTab',
+                        postId: res.postId || '',
+                        shareLinkId: res.shareLinkId || '',
+                        'channel-name': res.channelName,
+                        reason
+                    })
+                }, 5000)
             });
 
             let url = 'https://twitter.com/search?q=%23denet'

+ 3 - 3
src/logic/content/ParseCard.js

@@ -307,16 +307,16 @@ class ParseCard {
         return _iframe
     }
     createIframe({ post_Id = '', tweet_Id = '', tweet_author = '', page_type = '' }, if_center = false) {
+        let _iframeId = `denet-${guid()}`
         let _iframe = document.createElement('iframe')
         let _iframe_url = ''
         let tweet_str = ''
         if (tweet_Id) {
             tweet_str = `&tweetId=${tweet_Id}`
         }
-        _iframe.id = post_Id
+        _iframe.id = _iframeId
         _iframe.dataset.card = 'denet'
-        _iframe_url = getInnerIframeURL(`${iframeHost}/red-pack` + `?postId=${post_Id}${tweet_str}&tweet_author=${tweet_author}&window_origin=${window.location.origin}&page_type=${page_type}&iframeId=${_iframe.id}`);
-        // _iframe_url = chromeExtensionUrl + ('iframe/red-packet.html') + `?postId=${post_Id}${tweet_str}&tweet_author=${tweet_author}&window_origin=${window.location.origin}&page_type=${page_type}`;
+        _iframe_url = getInnerIframeURL(`${iframeHost}/red-pack` + `?postId=${post_Id}${tweet_str}&tweet_author=${tweet_author}&window_origin=${window.location.origin}&page_type=${page_type}&iframeId=${_iframeId}`);
         // debugger mode
         if (window.location.href.includes('denet_debugger')) {
             _iframe_url = _iframe_url + '&denet_debugger=1'

+ 37 - 33
src/logic/content/help/doTask.js

@@ -1,6 +1,6 @@
 import messageCenter from '@/uilts/messageCenter/content';
-import { getCookie } from '@/uilts/help'
-
+import { getCookie, isMobileTwitter } from '@/uilts/help'
+import axios from 'axios';
 
 const TwitterApiCreateTweet = ({ info, data }) => {
     let params = {
@@ -29,7 +29,8 @@ const TwitterApiCreateTweet = ({ info, data }) => {
             "dark_request": false
         }
     };
-    axios.post(`https://twitter.com/i/api/graphql/hC1nuE-2d1NX5LYBuuAvtQ/CreateTweet`,
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/graphql/K9It0MijE2UOlX-8wLyPYA/CreateTweet" : "https://twitter.com/i/api/graphql/hC1nuE-2d1NX5LYBuuAvtQ/CreateTweet"
+    axios.post(url,
         params, {
         headers: {
             "accept": "*/*",
@@ -55,7 +56,8 @@ const TwitterApiCreateTweet = ({ info, data }) => {
 }
 
 const TwitterLikeAPI = ({ info, data }) => {
-    fetch("https://twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet", {
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet" : "https://twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet"
+    fetch(url, {
         "headers": {
             "accept": "*/*",
             "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
@@ -86,35 +88,36 @@ const TwitterLikeAPI = ({ info, data }) => {
     })
 }
 
-// const TwitterFollowAPI = ({ info, data }) => {
-//     // 
-//     fetch("https://twitter.com/i/api/1.1/friendships/create.json", {
-//         "headers": {
-//             "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
-//             "content-type": "application/x-www-form-urlencoded",
-//             "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"",
-//             "sec-ch-ua-mobile": "?0",
-//             "sec-ch-ua-platform": "\"macOS\"",
-//             "x-csrf-token": getCookie('ct0'),
-//             "x-twitter-active-user": "yes",
-//             "x-twitter-auth-type": "OAuth2Session",
-//             "x-twitter-client-language": "zh-cn"
-//         },
-//         "referrer": "https://twitter.com/home",
-//         "referrerPolicy": "strict-origin-when-cross-origin",
-//         "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=" + data.follow_name + "",
-//         "method": "POST",
-//         "mode": "cors",
-//         "credentials": "include"
-//     }).then(() => {
-//         messageCenter.send({ info, data: { task_done: true, follow_name: data.follow_name } })
-//     }).catch(() => {
-//         messageCenter.send({ info, data: { task_done: false, follow_name: data.follow_name } })
-//     })
-// }
+const TwitterFollowAPI = ({ info, data }) => {
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/1.1/friendships/create.json" : "https://twitter.com/i/api/1.1/friendships/create.json"
+    fetch(url, {
+        "headers": {
+            "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
+            "content-type": "application/x-www-form-urlencoded",
+            "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"",
+            "sec-ch-ua-mobile": "?0",
+            "sec-ch-ua-platform": "\"macOS\"",
+            "x-csrf-token": getCookie('ct0'),
+            "x-twitter-active-user": "yes",
+            "x-twitter-auth-type": "OAuth2Session",
+            "x-twitter-client-language": "zh-cn"
+        },
+        "referrer": "https://twitter.com/home",
+        "referrerPolicy": "strict-origin-when-cross-origin",
+        "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=" + data.twitterUserId + "",
+        "method": "POST",
+        "mode": "cors",
+        "credentials": "include"
+    }).then(() => {
+        messageCenter.send({ info, data: { task_done: true, follow_name: data.follow_name } })
+    }).catch(() => {
+        messageCenter.send({ info, data: { task_done: false, follow_name: data.follow_name } })
+    })
+}
 
 const TwitterRetweetAPI = ({ info, data }) => {
-    fetch("https://twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet", {
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet" : "https://twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet"
+    fetch(url, {
         "headers": {
             "accept": "*/*",
             "accept-language": "zh,en;q=0.9,zh-CN;q=0.8",
@@ -147,5 +150,6 @@ const TwitterRetweetAPI = ({ info, data }) => {
 export default {
     TwitterApiCreateTweet,
     TwitterLikeAPI,
-    TwitterRetweetAPI
-}
+    TwitterRetweetAPI,
+    TwitterFollowAPI
+}

+ 33 - 0
src/logic/content/help/getData.js

@@ -0,0 +1,33 @@
+import messageCenter from '@/uilts/messageCenter/content';
+import { getCookie, isMobileTwitter } from '@/uilts/help'
+import axios from 'axios';
+
+const TwitterApiGetUserInfoByName = ({info, data}) => {
+  let url = isMobileTwitter() ? `https://mobile.twitter.com/i/api/graphql/gr8Lk09afdgWo7NvzP89iQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22${data.screen_name}%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D` : `https://twitter.com/i/api/graphql/mCbpQvZAw6zu_4PvuAUVVQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22${data.screen_name}%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D`
+  axios.get(url, {
+      headers: {
+          "accept": "*/*",
+          "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
+          "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
+          "content-type": "application/json",
+          "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\", \"Google Chrome\";v=\"101\"",
+          "sec-ch-ua-mobile": "?0",
+          "sec-ch-ua-platform": "\"Windows\"",
+          "sec-fetch-dest": "empty",
+          "sec-fetch-mode": "cors",
+          "sec-fetch-site": "same-origin",
+          "x-csrf-token": getCookie('ct0'),
+          "x-twitter-active-user": "yes",
+          "x-twitter-auth-type": "OAuth2Session",
+          "x-twitter-client-language": "en"
+      }
+  }).then(res => {
+    messageCenter.send({ info, data: res.data.data, })
+  }).catch(err => {
+    messageCenter.send({ info, data: {err} })
+  })
+}
+
+export default {
+  TwitterApiGetUserInfoByName
+}

+ 182 - 76
src/logic/content/twitter.js

@@ -1,5 +1,5 @@
 import { getChromeStorage, setChromeStorage, chromeExtensionUrl } from '@/uilts/chromeExtension.js'
-import { throttle, getQueryString, getCookie, nextTick, getQueryStringByUrl, getStorage, setStorage, getInnerIframeURL } from '@/uilts/help'
+import { throttle, getQueryString, getCookie, nextTick, getQueryStringByUrl, getStorage, setStorage, getInnerIframeURL, isMobileTwitter } from '@/uilts/help'
 import { discordAuthRedirectUri, iframeHost } from '@/http/configAPI'
 import { reportSrcPublishEvent } from '@/http/publishApi'
 
@@ -680,11 +680,22 @@ function createTweetToolbarToolBox() {
 function addSliderNavDeBtn() {
     try {
         let isSmall = false;
+        let isFloating = false;
+        let floatingTweetBtn;
         let tweetBtn = document.querySelector('a[data-testid="SideNav_NewTweet_Button"]');
-        if (tweetBtn && tweetBtn.querySelector('svg')) {
-            isSmall = true;
+        if (tweetBtn) {
+            if (tweetBtn.querySelector('svg')) {
+                isSmall = true;
+            }
+        } else {
+            // 手机打开twitter 发推按钮
+            floatingTweetBtn = document.querySelector('div[data-testid="FloatingActionButtonBase"]');
+            if (floatingTweetBtn) {
+                isFloating = true;
+            }
         }
-        if (!isSmall) {
+
+        if (!isSmall && !isFloating) {
             let bigDom = document.querySelector('a[href="/compose/tweet"]').parentNode.parentNode;
             let deBtn = document.getElementById('de-btn');
             if (bigDom && !deBtn) {
@@ -696,15 +707,19 @@ function addSliderNavDeBtn() {
                 });
             }
         } else {
-            let smallDom = document.querySelector('a[href="/compose/tweet"]').parentNode.parentNode;
             let deBtn3 = document.getElementById('de-btn3');
-            if (smallDom && !deBtn3) {
-                dom && dom.deBtn3 && smallDom.appendChild(dom.deBtn3);
-                Report.reportLog({
-                    pageSource: Report.pageSource.mainPage,
-                    businessType: Report.businessType.buttonView,
-                    objectType: Report.objectType.buttonMain
-                });
+            if (isFloating && !deBtn3) {
+                floatingTweetBtn.appendChild(dom.deBtn3);
+            } else {
+                let smallDom = document.querySelector('a[href="/compose/tweet"]').parentNode.parentNode;
+                if (smallDom && !deBtn3) {
+                    dom && dom.deBtn3 && smallDom.appendChild(dom.deBtn3);
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonMain
+                    });
+                }
             }
         }
     } catch (e) {
@@ -1072,7 +1087,7 @@ export function init() {
 }
 
 export const getTweetUserFollowStatus = (params) => {
-    let { tweetId, userList } = params.data;
+    let { tweetId, userList, iframeGUId, type } = JSON.parse(params.data);
     let promiseList = [];
     for (let i = 0; i < userList.length; i++) {
         promiseList[i] = TwitterApiUserByScreenNameReq({ screen_name: userList[i]['name'] });
@@ -1089,10 +1104,28 @@ export const getTweetUserFollowStatus = (params) => {
                 }
             }
         }
+        messageCenter.send({
+            info: {
+                iframeId: params.iframeId,
+                actionType: 'CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES'
+            },
+            data: {
+                list, tweetId, type, iframeId: params.iframeId, iframeGUId
+            }
+        })
 
-        chrome.runtime.sendMessage({ actionType: 'CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES', data: list, tweetId, type: params.type, iframeId: params.iframeId }, () => { })
+        // chrome.runtime.sendMessage({ actionType: 'CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES', data: list, tweetId, type: params.type, iframeId: params.iframeId }, () => { })
     }).catch(err => {
-        chrome.runtime.sendMessage({ actionType: 'CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES', data: [], tweetId, type: params.type, iframeId: params.iframeId }, () => { })
+        messageCenter.send({
+            info: {
+                iframeId: params.iframeId,
+                actionType: 'CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES'
+            },
+            data: {
+                list: [], tweetId, type, iframeId: params.iframeId, iframeGUId
+            }
+        })
+        // chrome.runtime.sendMessage({ actionType: 'CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES', data: [], tweetId, type: params.type, iframeId: params.iframeId }, () => { })
     })
 }
 
@@ -1141,8 +1174,8 @@ export function facebookReplyTweet({ info, data }) {
     }
 }
 
-export function replyHandle({ info, data}) {
-    let iframe = window.parent.document.getElementById(data.postId);
+export function replyHandle(params) {
+    let iframe = window.parent.document.getElementById(params.iframeId);
     let replyBtn = iframe.parentNode.parentNode.querySelector('div[data-testid="reply"]') ||
         iframe.parentNode.parentNode.parentNode.querySelector('div[data-testid="reply"]');
     if (replyBtn) {
@@ -1164,16 +1197,9 @@ export function replyHandle({ info, data}) {
                 });
 
                 let eleList = tweetReply.parentNode.parentNode.parentNode.parentNode.parentNode.querySelectorAll('span[data-text="true"]');
-                reportReplyResult(eleList, data, () => {
-                    contentMessageCenter.send({
-                        info: {
-                            actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH',
-                            iframeId: info.iframeId
-                        },
-                        data: { postId: data.postId }
-                    })
-                    // iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH', data: {} }, '*');
-                    // chrome.runtime.sendMessage({ actionType: "CONTENT_RED_PACKET_REPLY_RASK_FINSH", data: { postId: data.postId } }, () => { })
+                reportReplyResult(eleList, params, () => {
+                    iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH', data: { postId: params.postId } }, '*');
+                    // chrome.runtime.sendMessage({ actionType: "CONTENT_RED_PACKET_REPLY_RASK_FINSH", data: { postId: params.postId } }, () => { })
                 });
             })
         }
@@ -1181,7 +1207,7 @@ export function replyHandle({ info, data}) {
 }
 
 export function onTweetReplyClick(params) {
-    let iframe = window.parent.document.getElementById(params.postId);
+    let iframe = window.parent.document.getElementById(params.iframeId);
     let replyBtn = iframe.parentNode.parentNode.querySelector('div[data-testid="reply"]') ||
         iframe.parentNode.parentNode.parentNode.querySelector('div[data-testid="reply"]');
     if (replyBtn) {
@@ -1229,8 +1255,8 @@ function onReplyDialogOpen(params, iframe) {
                 let eleList = dialog.querySelector('div[contenteditable="true"]').querySelectorAll('span[data-text="true"]');
                 reportReplyResult(eleList, params, () => {
                     // 上報完成
-                    // iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH', data: {} }, '*');
-                    chrome.runtime.sendMessage({ actionType: "CONTENT_RED_PACKET_REPLY_RASK_FINSH", data: { postId: params.postId } }, () => { })
+                    iframe.contentWindow.postMessage({ actionType: 'CONTENT_RED_PACKET_REPLY_RASK_FINSH', data: { postId: params.postId } }, '*');
+                    // chrome.runtime.sendMessage({ actionType: "CONTENT_RED_PACKET_REPLY_RASK_FINSH", data: { postId: params.postId } }, () => { })
                 })
             });
         }
@@ -1473,6 +1499,35 @@ export function doTaskTwitterAPI({ info, data }) {
     }
 }
 
+export function doTaskIframeTwitterAPI(params) {
+    let { tweet_Id, tweet_text, task_type, tasks, iframeGUId } = JSON.parse(params.data);
+    if (task_type == 'tasks') {
+        tasks.forEach((item) => {
+            switch (String(item.type)) {
+                // 关注指定用户
+                case '1':
+                    item.relatedUsers.forEach((item) => {
+                        if (item.name && item.twitterUserId) {
+                            TwitterFollowAPI(item, tweet_Id);
+                        }
+                    })
+                    break
+                // 点赞
+                case '2':
+                    TwitterLikeAPI(tweet_Id)
+                    break
+                // 推文发推
+                case '10':
+                    // 发推
+                    TwitterApiCreateTweet({ text: tweet_text, tweet_Id, iframeId: params.iframeId, iframeGUId, iframeMsg: true })
+                    break
+            }
+        })
+    } else if (task_type == 'like') {
+        TwitterLikeAPI(tweet_Id)
+    }
+}
+
 export function showJoinDialog(data) {
     let iframe = document.querySelector('#nftProjectId')
     iframe.style.display = 'block'
@@ -1500,7 +1555,8 @@ const TwitterFriendshipsUpdate = (params) => {
     if (!id) {
         return;
     }
-    return fetch("https://twitter.com/i/api/1.1/friendships/update.json", {
+    let url = isMobileTwitter() ? 'https://mobile.twitter.com/i/api/1.1/friendships/update.json' : "https://twitter.com/i/api/1.1/friendships/update.json";
+    return fetch(url, {
         "headers": {
             "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
             "content-type": "application/x-www-form-urlencoded",
@@ -1522,9 +1578,9 @@ const TwitterFriendshipsUpdate = (params) => {
     })
 }
 
-const TwitterFollowAPI = (item, tweet_Id, info) => {
-    console.log('TwitterFollowAPI', item, tweet_Id, info)
-    fetch("https://twitter.com/i/api/1.1/friendships/create.json", {
+const TwitterFollowAPI = (item, tweet_Id) => {
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/1.1/friendships/create.json" : "https://twitter.com/i/api/1.1/friendships/create.json"
+    fetch(url, {
         "headers": {
             "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
             "content-type": "application/x-www-form-urlencoded",
@@ -1567,8 +1623,9 @@ const TwitterFollowAPI = (item, tweet_Id, info) => {
 }
 
 
-const TwitterRetweetAPI = (tweet_Id, info) => {
-    fetch("https://twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet", {
+const TwitterRetweetAPI = (tweet_Id) => {
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet" : "https://twitter.com/i/api/graphql/ojPdsZsimiJrUGLR1sjUtA/CreateRetweet"
+    fetch(url, {
         "headers": {
             "accept": "*/*",
             "accept-language": "zh,en;q=0.9,zh-CN;q=0.8",
@@ -1611,8 +1668,9 @@ const TwitterRetweetAPI = (tweet_Id, info) => {
     })
 }
 
-const TwitterLikeAPI = (tweet_Id, info) => {
-    fetch("https://twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet", {
+const TwitterLikeAPI = (tweet_Id) => {
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet" : "https://twitter.com/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet"
+    fetch(url, {
         "headers": {
             "accept": "*/*",
             "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
@@ -1655,7 +1713,8 @@ const TwitterLikeAPI = (tweet_Id, info) => {
     })
 }
 
-const TwitterApiCreateTweet = ({ text, tweet_Id, iframeId }) => {
+const TwitterApiCreateTweet = ({ text, tweet_Id, iframeId,
+    iframeGUId, iframeMsg }) => {
     let data = {
         queryId: "hC1nuE-2d1NX5LYBuuAvtQ",
         features: {
@@ -1665,7 +1724,9 @@ const TwitterApiCreateTweet = ({ text, tweet_Id, iframeId }) => {
             "vibe_api_enabled": true,
             "responsive_web_edit_tweet_api_enabled": false,
             "standardized_nudges_misinfo": true,
-            "responsive_web_enhance_cards_enabled": false
+            "responsive_web_enhance_cards_enabled": false,
+            "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": false,
+            "responsive_web_text_conversations_enabled": false
         },
         variables: {
             "tweet_text": text,
@@ -1682,7 +1743,8 @@ const TwitterApiCreateTweet = ({ text, tweet_Id, iframeId }) => {
             "dark_request": false
         }
     };
-    axios.post(`https://twitter.com/i/api/graphql/hC1nuE-2d1NX5LYBuuAvtQ/CreateTweet`,
+    let url = isMobileTwitter() ? "https://mobile.twitter.com/i/api/graphql/K9It0MijE2UOlX-8wLyPYA/CreateTweet" : "https://twitter.com/i/api/graphql/hC1nuE-2d1NX5LYBuuAvtQ/CreateTweet"
+    axios.post(url,
         data, {
         headers: {
             "accept": "*/*",
@@ -1701,15 +1763,43 @@ const TwitterApiCreateTweet = ({ text, tweet_Id, iframeId }) => {
             "x-twitter-client-language": "en"
         },
     }).then(function (response) {
-        chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet1', task_data: '', task_done: '是', response, iframeId })
+        console.log(response)
+        let data = response.data;
+        if (iframeMsg) {
+            messageCenter.send({
+                info: {
+                    iframeId,
+                    actionType: 'CONTENT_CREATE_TWEET_FINISH'
+                },
+                data: {
+                    tweet_Id, iframeId, iframeGUId, response: data, done: true
+                }
+            })
+        } else {
+            chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet1', task_data: '', task_done: '是', response, iframeId })
+        }
     }).catch(function (err) {
-        chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet1', task_data: '', task_done: '否', iframeId })
+        console.log('err --1', err)
+        if (iframeMsg) {
+            messageCenter.send({
+                info: {
+                    iframeId,
+                    actionType: 'CONTENT_CREATE_TWEET_FINISH'
+                },
+                data: {
+                    tweet_Id, iframeId, iframeGUId, done: false
+                }
+            })
+        } else {
+            chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet1', task_data: '', task_done: '否', iframeId })
+        }
     });
 }
 
 const TwitterApiUserByScreenNameReq = (params) => {
     let { screen_name } = params || {};
-    return axios.get(`https://twitter.com/i/api/graphql/mCbpQvZAw6zu_4PvuAUVVQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22${screen_name}%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D`, {
+    let url = isMobileTwitter() ? `https://mobile.twitter.com/i/api/graphql/gr8Lk09afdgWo7NvzP89iQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22${screen_name}%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D` : `https://twitter.com/i/api/graphql/mCbpQvZAw6zu_4PvuAUVVQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22${screen_name}%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D`
+    return axios.get(url, {
         headers: {
             "accept": "*/*",
             "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
@@ -1730,33 +1820,39 @@ const TwitterApiUserByScreenNameReq = (params) => {
 }
 
 
-export const TwitterApiUserByScreenName = ({info, data}) => {
-    let { screen_name, tweetId = '', objectType = '', iframeId = '' } = params;
+export const TwitterApiUserByScreenName = (params, cb) => {
+    let { screen_name, tweetId = '', objectType = '', iframeId = '', iframeMsg = false, iframeGUId } = params;
 
     TwitterApiUserByScreenNameReq({ screen_name }).then(function (response) {
-       contentMessageCenter.send({
-            info,
-            data: {
-                data: response.data.data || {},
-                tweetId,
-                objectType,
-                iframeId
-            }
-        })
-        // treasure 使用 runtime
-        chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: response.data.data || {}, tweetId, objectType, iframeId }, () => { })
+        if (iframeMsg) {
+            messageCenter.send({
+                info: {
+                    iframeId,
+                    actionType: 'CONTENT_API_GET_TWEET_USER_INFO_END'
+                },
+                data: {
+                    iframeGUId, response: response.data.data || {}, objectType
+                }
+            })
+        } else {
+            chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: response.data.data || {}, tweetId, objectType, iframeId }, () => { })
+        }
+
     }).catch(function (err) {
-       contentMessageCenter.send({
-            info,
-            data: {
-                data: {},
-                tweetId,
-                objectType,
-                iframeId
-            }
-        })
-        // treasure 使用 runtime
-        chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: {}, tweetId, objectType, iframeId }, () => { })
+        if (iframeMsg) {
+            messageCenter.send({
+                info: {
+                    iframeId,
+                    actionType: 'CONTENT_API_GET_TWEET_USER_INFO_END'
+                },
+                data: {
+                    iframeGUId, response: {}, objectType
+
+                }
+            })
+        } else {
+            chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: {}, tweetId, objectType, iframeId }, () => { })
+        }
     });
 }
 
@@ -2815,16 +2911,26 @@ export const showPublishDialog = () => {
 }
 
 // 获取推文发送回去
-export const sendContentByTwitterID = (tweet_Id) => {
+export const sendContentByTwitterID = (params) => {
+    let { tweet_Id, iframeGUId } = JSON.parse(params.data);
     // 获取内容
-    let txt = parseCard.getContentByTwitterId(tweet_Id)
-    // 发送
-    chrome.runtime.sendMessage({
-        actionType: "CONTENT_GET_TWEET_TXT", data: {
-            tweet_Id,
-            txt
-        }
+    let txt = parseCard.getContentByTwitterId(tweet_Id);
+    messageCenter.send({
+      info: {
+          iframeId: params.iframeId,
+          actionType: 'CONTENT_GET_TWEET_TXT'
+      },
+      data: {
+          tweet_Id, txt, iframeGUId
+      }
     })
+    // 发送
+    // chrome.runtime.sendMessage({
+    //     actionType: "CONTENT_GET_TWEET_TXT", data: {
+    //         tweet_Id,
+    //         txt
+    //     }
+    // })
 }
 
 export const sendLoginSuccessToAllIframe = () => { 

+ 2 - 2
src/manifest.json

@@ -2,8 +2,8 @@
     "manifest_version": 3,
     "name": "DeNet",
     "description": "Growing more twitter followers with Denet",
-    "version": "1.1.7.2",
-    "denet_app_version_code": "22",
+    "version": "1.1.7.4",
+    "denet_app_version_code": "24",
     "background": {
         "service_worker": "/js/background.js"
     },

+ 8 - 0
src/uilts/help.js

@@ -321,3 +321,11 @@ export const getBeforeTimeFormat = (timestamp) => {
   let _s = moment.duration(_d1.diff(_d2)).seconds()
   return plural(_s, 'sec')
 }
+
+export function isMobileTwitter() {
+  let isMobile = false;
+  if(window.location.href.startsWith('https://mobile.twitter.com')) {
+    isMobile = true;
+  }
+  return isMobile;
+}

+ 3 - 0
src/uilts/messageCenter/iframe/messageEnum.js

@@ -15,6 +15,9 @@ const SEND_MESSAGE_ENUM = {
     // ---- 获取推文内容 ----
     IFRAME_DOM_GET_TWEET_TEXT: 'IFRAME_DOM_GET_TWEET_TEXT',
 
+    // ---- 获取twitter用户信息 ----
+    IFRAME_GET_TWITTER_USER_INFO: 'IFRAME_GET_TWITTER_USER_INFO',
+
 
 }
 

+ 39 - 0
src/view/components/loading.vue

@@ -0,0 +1,39 @@
+<template>
+    <img :src="icon" alt="" class="loading"
+        :style="{ 'width': `${width}px`, 'height': `${height}px`, 'margin-left': `-${width / 2}px`, 'margin-top': `-${height / 2}px` }" />
+</template>
+<script setup>
+import { defineProps } from "vue";
+const props = defineProps({
+    width: {
+        type: Number,
+        default: 40
+    },
+    height: {
+        type: Number,
+        default: 40
+    },
+    icon: {
+        type: String,
+        default: require('@/assets/svg/icon-loading-gray2.svg')
+    }
+})
+</script>
+<style lang="scss" scoped>
+.loading {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    animation: rotation 1s linear infinite;
+}
+
+@keyframes rotation {
+    from {
+        -webkit-transform: rotate(0deg);
+    }
+
+    to {
+        -webkit-transform: rotate(360deg);
+    }
+}
+</style>

+ 24 - 14
src/view/iframe/publish/components/get-more.vue

@@ -1,23 +1,26 @@
 <template>
-    <div class="get-more-btns"  v-if="props.style_type == 3">
+    <div class="get-more-btns" v-if="props.style_type == 3">
         <div class="get-more-btn" @click="jumpMore">
             <img width="22" :src="require('@/assets/svg/icon-wallet-success.svg')" />
-            <font>View wallet</font>
+            <span>View wallet</span>
         </div>
         <div class="get-more-btn" @click="jumpMore">
             <img width="22" :src="require('@/assets/svg/icon-big-give.svg')" />
-            <font>Get More Giveaway</font>
+            <span>Get More Giveaway</span>
         </div>
     </div>
     <div class="getMore" @click="jumpMore" v-if="props.style_type == 1">
         <img width="20" :src="require('@/assets/svg/icon-big-give.svg')" />
-        <font>Get More Giveaway</font>
+        <span>Get More Giveaway</span>
         <img height="20" :src="require('@/assets/svg/icon-cell-arrow-right.svg')" />
     </div>
     <div class="get_more" v-if="props.style_type == 2" @click="jumpMore">
         <img width="18" :src="require('@/assets/svg/icon-big-give.svg')" />
         <span>Get More Giveaway</span>
     </div>
+    <div v-if="style_type == 4" @click="jumpMore">
+        <slot></slot>
+    </div>
 </template>
 
 <script setup>
@@ -48,13 +51,16 @@ onBeforeMount(() => {
 })
 
 const jumpMore = () => {
-    Report.reportLog({
-      pageSource: props.reportData.pageSource,
-      businessType: Report.businessType.buttonClick,
-      objectType: Report.objectType.getMoreGiveaway,
-      postId: props.reportData.postId,
-      redPacketType: props.reportData.redPacketType
-    });
+    if (props.reportData) {
+        Report.reportLog({
+            pageSource: props.reportData.pageSource,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.getMoreGiveaway,
+            postId: props.reportData.postId,
+            redPacketType: props.reportData.redPacketType
+        });
+    }
+
     if (moreUrl.value) {
         window.open(moreUrl.value)
     }
@@ -76,7 +82,7 @@ const jumpMore = () => {
         margin: 0 5px;
     }
 
-    font {
+    span {
         color: #000;
         font-size: 15px;
         font-weight: 500;
@@ -100,7 +106,8 @@ const jumpMore = () => {
         margin-right: 8px;
     }
 }
-.get-more-btns  {
+
+.get-more-btns {
     display: flex;
     cursor: pointer;
     user-select: none;
@@ -109,6 +116,7 @@ const jumpMore = () => {
     padding: 13px 0;
     box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.06);
     position: relative;
+
     .get-more-btn {
         flex: 1;
         display: flex;
@@ -118,6 +126,7 @@ const jumpMore = () => {
         align-items: center;
         justify-content: center;
         height: 44px;
+
         font {
             font-weight: 600;
             font-size: 14px;
@@ -127,6 +136,7 @@ const jumpMore = () => {
             color: #000000;
         }
     }
+
     &::after {
         content: "";
         width: 1px;
@@ -134,7 +144,7 @@ const jumpMore = () => {
         position: absolute;
         left: 50%;
         top: 13px;
-        background-color: rgba(0,0,0,.2);
+        background-color: rgba(0, 0, 0, .2);
         transform: scale(0.5);
         transform-origin: 0 0;
     }

+ 61 - 78
src/view/iframe/red-packet/luck-draw.vue

@@ -470,6 +470,7 @@ import { getInviteGuildInfo } from "@/http/discordApi";
 import GlobalTip from '@/view/components/global-tip.vue';
 import customCardCover from '@/view/components/custom-card-cover.vue';
 import { RewardType, PlayType } from "@/types";
+import denet from '@/denet'
 
 var moment = require('moment');
 
@@ -579,13 +580,8 @@ async function clickLikeBtn() {
             break
         case '3':
             state.loading_show = true
-            chrome.tabs.getCurrent((tab) => {
-                chrome.tabs.sendMessage(tab.id, {
-                    actionType: "IFRAME_TWITTER_API_DO_TASK", task_data: {
-                        tweet_Id: state.tweetId
-                    }, task_type: 'like'
-                }, (res) => { console.log(res) });
-            })
+            let likeRes = await denet.content.doTask.like({ tweetId: state.tweetId });
+            likeRes && doTaskReport({...likeRes, task_type: 'like', do_type: 'api'}, {tab: {}});
             break
         default:
             window.open(`https://twitter.com/intent/like?tweet_id=${state.tweetId}`)
@@ -696,13 +692,8 @@ async function clickRetweetBtn() {
             break
         case '3':
             state.loading_show = true
-            chrome.tabs.getCurrent((tab) => {
-                chrome.tabs.sendMessage(tab.id, {
-                    actionType: "IFRAME_TWITTER_API_DO_TASK", task_data: {
-                        tweet_Id: state.tweetId
-                    }, task_type: 'retweet'
-                }, (res) => { console.log(res) });
-            })
+            let retweetRes = await denet.content.doTask.reTweet({ tweetId: state.tweetId });
+            retweetRes && doTaskReport({...retweetRes, task_type: 'retweet', do_type: 'api'}, {tab: {}});
             break
         default:
             window.open(`https://twitter.com/intent/retweet?tweet_id=${state.tweetId}`)
@@ -761,6 +752,7 @@ async function clickReply(params) {
 
     let replyData = {
         postId: state.postId,
+        iframeId: state.iframeId,
         type: params.type,
         taskLuckdropId: state.detail.taskLuckdropId
     }
@@ -850,7 +842,8 @@ function feacebookShareUrl(params = {}) {
     let { href = '', type = '', taskLuckdropId } = params;
     let cbParams = JSON.stringify({
         type,
-        taskLuckdropId
+        taskLuckdropId,
+        iframeId: state.iframeId
     })
     let shareUrl = `https://www.facebook.com/dialog/share?app_id=${facebookAppConfig.facebookAppId}&display=popup&href=${href}&redirect_uri=${facebookAppConfig.faceShareRedirectUrl}?params=${cbParams}`;
 
@@ -1012,16 +1005,20 @@ async function clickFollowAll(item, is_all) {
             arr_name.forEach((item) => {
                 follow_data.push(item)
             })
-            state.loading_show = true
-            chrome.tabs.getCurrent((tab) => {
-                chrome.tabs.sendMessage(tab.id, {
-                    actionType: "IFRAME_TWITTER_API_DO_TASK",
-                    task_data: {
-                        tweet_Id: state.tweetId,
-                        follow_data: follow_data,
-                    },
-                    task_type: 'follow'
-                }, (res) => { console.log(res) });
+            state.loading_show = true;
+            let promiseList = [];
+            for (let i = 0; i < follow_data.length; i++) {
+                promiseList[i] = denet.content.doTask.follows({ follow_name: follow_data[i]['name'], twitterUserId: follow_data[i]['twitterUserId'] });
+            }
+
+            Promise.allSettled(promiseList).then((res) => {
+                if (res && res.length) {
+                    let resList = res.filter(item => item.status == 'fulfilled');
+                    for (let i = 0; i < resList.length; i++) {
+                      let item = resList[i].value;
+                      item && doTaskReport({...item, task_type: 'follow', task_data: {follow_name: item.follow_name}, do_type: 'api'}, {tab: {}});
+                    }
+                }
             })
 
             break
@@ -1072,16 +1069,38 @@ const reSetBindTwtterId = (_params) => {
     })
 }
 
-const reportBindTweetSuccess = (params) => {
+const reportBindTweetSuccess = async (params) => {
     let { discordTask, srcUserId } = params || {};
     discordTaskDetail = discordTask;
-    sendCurrentTabMessage({
-        actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
-        data: {
-            screen_name: srcUserId,
-            tweetId: state.tweetId
-        }
-    })
+
+    let {user = {}} = await denet.content.getData.getUserInfoByName({ screen_name: srcUserId });
+    if (user && user.result && user.result.legacy) {
+      let legacy = user.result.legacy;
+      reportParams.twitterFans = legacy ? legacy.followers_count : 0;
+
+      if (!discordTaskDetail) {
+          if (reportParams.hasReport) return;
+          reportParams.hasReport = true;
+          Report.reportLog({
+              objectType: Report.objectType.tweetPostBinded,
+              twitterFans: reportParams.twitterFans,
+              redPacketType: 1,
+              postId: state.postId
+          });
+      } else {
+          if (reportParams.discordFans !== '') {
+              if (reportParams.hasReport) return;
+              reportParams.hasReport = true;
+              Report.reportLog({
+                  objectType: Report.objectType.tweetPostBinded,
+                  twitterFans: reportParams.twitterFans,
+                  discordFans: reportParams.discordFans,
+                  redPacketType: 1,
+                  postId: state.postId
+              });
+          }
+      }
+    }
 
     if (discordTask) {
         getDiscordInfo({ inviteUrl: JSON.parse(discordTask.bizData).inviteUrl }, (res) => {
@@ -1455,7 +1474,7 @@ function initTaskDetail(cb) {
 let tab_index = 0
 const doTaskReport = (req, sender) => {
     state.loading_show = false
-    let follow_name = req.task_data.follow_name || ''
+    let follow_name = req.task_data ? req.task_data.follow_name : '';
     // 1 Twitter follow Twitter ScreenName
     // 2 Tweet like
     // 3 Retweet
@@ -1564,6 +1583,8 @@ onMounted(() => {
     state.process_mode = process.env.NODE_ENV
     state.postId = getQueryString('postId')
     state.window_origin = getQueryString('window_origin') || '';
+    state.iframeId = getQueryString('iframeId') || ''
+
     if (state.window_origin.indexOf('twitter.com') > -1) {
         state.tweetId = getQueryString('tweetId')
         state.tweet_author = getQueryString('tweet_author');
@@ -1964,12 +1985,14 @@ function handleErrorCode(res) {
 //   });
 // }
 function onWindowMessage() {
-    window.addEventListener("message", function (event) {
+    window.onmessage = function (event) {
         if (event.data) {
             switch (event.data.actionType) {
                 case 'CONTENT_RED_PACKET_REPLY_RASK_FINSH':
-                    state.done.reply = true;
-                    state.done.reply_red = false;
+                    if (event.data.data.postId == state.postId) {
+                        state.done.reply = true;
+                        state.done.reply_red = false;
+                    }
                     break;
                 case 'CONTENT_RED_PACKET_GET_TWEET_AUTHOR':
                     fullName = event.data.data.fullName
@@ -1979,7 +2002,7 @@ function onWindowMessage() {
                     break;
             }
         }
-    });
+    }
 }
 
 function onPageVisbile() {
@@ -2008,42 +2031,6 @@ function onRuntimeMsg() {
                 state.loading_show = false
                 doTaskReport(req, sender);
                 break;
-            case 'CONTENT_RED_PACKET_REPLY_RASK_FINSH':
-                if (req.data && req.data.postId == state.postId) {
-                    state.done.reply = true;
-                    state.done.reply_red = false;
-                }
-                break;
-            case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
-                let { user } = req.data || {};
-                if (req.tweetId == state.tweetId && user && user.result && user.result.legacy) {
-                    let legacy = user.result.legacy;
-                    reportParams.twitterFans = legacy ? legacy.followers_count : 0;
-
-                    if (!discordTaskDetail) {
-                        if (reportParams.hasReport) return;
-                        reportParams.hasReport = true;
-                        Report.reportLog({
-                            objectType: Report.objectType.tweetPostBinded,
-                            twitterFans: reportParams.twitterFans,
-                            redPacketType: 1,
-                            postId: state.postId
-                        });
-                    } else {
-                        if (reportParams.discordFans !== '') {
-                            if (reportParams.hasReport) return;
-                            reportParams.hasReport = true;
-                            Report.reportLog({
-                                objectType: Report.objectType.tweetPostBinded,
-                                twitterFans: reportParams.twitterFans,
-                                discordFans: reportParams.discordFans,
-                                redPacketType: 1,
-                                postId: state.postId
-                            });
-                        }
-                    }
-                }
-                break;
             case 'USER_SETTING':
                 setNotification(req.data)
                 break;
@@ -2171,10 +2158,6 @@ function discordAuth(actionState = 'default') {
                     type: 'normal',
                     url: authorizeUrl
                 }, function (window) {
-                    let windowId = window.id;
-                    callEventPageMethod("RED_PACKET_SAVE_DISCORD_AUTH_WINDOW_ID", {
-                        windowId: windowId
-                    });
                 })
             }
         }

+ 56 - 75
src/view/iframe/red-packet/red-packet.vue

@@ -425,6 +425,7 @@ import { getInviteGuildInfo } from "@/http/discordApi";
 import GlobalTip from '@/view/components/global-tip.vue'
 import customCardCover from '@/view/components/custom-card-cover.vue';
 import { RewardType, PlayType } from '@/types';
+import denet from '@/denet'
 
 var moment = require('moment');
 
@@ -529,13 +530,9 @@ async function clickLikeBtn() {
       break
     case '3':
       state.loading_show = true
-      chrome.tabs.getCurrent((tab) => {
-        chrome.tabs.sendMessage(tab.id, {
-          actionType: "IFRAME_TWITTER_API_DO_TASK", task_data: {
-            tweet_Id: state.tweetId
-          }, task_type: 'like'
-        }, (res) => { console.log(res) });
-      })
+      let likeRes = await denet.content.doTask.like({ tweetId: state.tweetId });
+      likeRes && doTaskReport({...likeRes, task_type: 'like', do_type: 'api'}, {tab: {}});
+
       break
     default:
       window.open(`https://twitter.com/intent/like?tweet_id=${state.tweetId}`)
@@ -644,13 +641,8 @@ async function clickRetweetBtn() {
       break
     case '3':
       state.loading_show = true
-      chrome.tabs.getCurrent((tab) => {
-        chrome.tabs.sendMessage(tab.id, {
-          actionType: "IFRAME_TWITTER_API_DO_TASK", task_data: {
-            tweet_Id: state.tweetId
-          }, task_type: 'retweet'
-        }, (res) => { console.log(res) });
-      })
+      let retweetRes = await denet.content.doTask.reTweet({ tweetId: state.tweetId });
+      retweetRes && doTaskReport({...retweetRes, task_type: 'retweet', do_type: 'api'}, {tab: {}});
       break
     default:
       window.open(`https://twitter.com/intent/retweet?tweet_id=${state.tweetId}`)
@@ -672,6 +664,7 @@ async function clickRetweetBtn() {
 function onTweetReplyClick(params) {
   let replyData = {
     postId: state.postId,
+    iframeId: state.iframeId,
     type: params.type,
     taskLuckdropId: state.detail.taskLuckdropId
   }
@@ -687,6 +680,7 @@ async function clickReply(params) {
 
   let replyData = {
     postId: state.postId,
+    iframeId: state.iframeId,
     type: params.type,
     taskLuckdropId: state.detail.taskLuckdropId
   }
@@ -895,17 +889,20 @@ async function clickFollowAll(item, is_all) {
         follow_data.push(item)
       })
       state.loading_show = true
-      chrome.tabs.getCurrent((tab) => {
-        chrome.tabs.sendMessage(tab.id, {
-          actionType: "IFRAME_TWITTER_API_DO_TASK",
-          task_data: {
-            tweet_Id: state.tweetId,
-            follow_data: follow_data,
-          },
-          task_type: 'follow'
-        }, (res) => { console.log(res) });
-      })
+      let promiseList = [];
+      for (let i = 0; i < follow_data.length; i++) {
+          promiseList[i] = denet.content.doTask.follows({ follow_name: follow_data[i]['name'], twitterUserId: follow_data[i]['twitterUserId'] });
+      }
 
+      Promise.allSettled(promiseList).then((res) => {
+        if (res && res.length) {
+            let resList = res.filter(item => item.status == 'fulfilled');
+            for (let i = 0; i < resList.length; i++) {
+              let item = resList[i].value;
+              item && doTaskReport({...item, task_type: 'follow', task_data: {follow_name: item.follow_name}, do_type: 'api'}, {tab: {}});
+            }
+        }
+      })
       break
     default:
       openFollowTabs(arr_name)
@@ -953,16 +950,37 @@ const reSetBindTwtterId = (_params) => {
   })
 }
 
-const reportBindTweetSuccess = (params) => {
+const reportBindTweetSuccess = async (params) => {
   let { discordTask, srcUserId } = params || {};
   discordTaskDetail = discordTask;
-  sendCurrentTabMessage({
-    actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
-    data: {
-      screen_name: srcUserId,
-      tweetId: state.tweetId
+  let {user = {}} = await denet.content.getData.getUserInfoByName({ screen_name: srcUserId });
+  if (user && user.result && user.result.legacy) {
+    let legacy = user.result.legacy;
+    reportParams.twitterFans = legacy ? legacy.followers_count : 0;
+
+    if (!discordTaskDetail) {
+        if (reportParams.hasReport) return;
+        reportParams.hasReport = true;
+        Report.reportLog({
+            objectType: Report.objectType.tweetPostBinded,
+            twitterFans: reportParams.twitterFans,
+            redPacketType: 1,
+            postId: state.postId
+        });
+    } else {
+        if (reportParams.discordFans !== '') {
+            if (reportParams.hasReport) return;
+            reportParams.hasReport = true;
+            Report.reportLog({
+                objectType: Report.objectType.tweetPostBinded,
+                twitterFans: reportParams.twitterFans,
+                discordFans: reportParams.discordFans,
+                redPacketType: 1,
+                postId: state.postId
+            });
+        }
     }
-  })
+  }
 
   if (discordTask) {
     getDiscordInfo({ inviteUrl: JSON.parse(discordTask.bizData).inviteUrl }, (res) => {
@@ -1291,7 +1309,8 @@ function initTaskDetail(cb) {
 let tab_index = 0
 const doTaskReport = (req, sender) => {
   state.loading_show = false
-  let follow_name = req.task_data.follow_name || ''
+  let follow_name = req.task_data ? req.task_data.follow_name : '';
+
   // 1 Twitter follow Twitter ScreenName
   // 2 Tweet like
   // 3 Retweet
@@ -1363,6 +1382,7 @@ const doTaskReport = (req, sender) => {
 onMounted(() => {
   state.process_mode = process.env.NODE_ENV
   state.postId = getQueryString('postId')
+  state.iframeId = getQueryString('iframeId') || ''
   state.window_origin = getQueryString('window_origin') || '';
   if (state.window_origin.indexOf('twitter.com') > -1) {
     state.tweetId = getQueryString('tweetId')
@@ -1763,8 +1783,10 @@ function onWindowMessage() {
     if (event.data) {
       switch (event.data.actionType) {
         case 'CONTENT_RED_PACKET_REPLY_RASK_FINSH':
-          state.done.reply = true;
-          state.done.reply_red = false;
+          if (event.data.data.postId == state.postId) {
+            state.done.reply = true;
+            state.done.reply_red = false;
+          }
           break;
         case 'CONTENT_RED_PACKET_GET_TWEET_AUTHOR':
           fullName = event.data.data.fullName
@@ -1803,43 +1825,6 @@ function onRuntimeMsg() {
         state.loading_show = false
         doTaskReport(req, sender);
         break;
-      case 'CONTENT_RED_PACKET_REPLY_RASK_FINSH':
-        if (req.data && req.data.postId == state.postId) {
-          state.done.reply = true;
-          state.done.reply_red = false;
-        }
-        break;
-      case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
-        let { user } = req.data || {};
-        if (req.tweetId == state.tweetId && user && user.result && user.result.legacy) {
-          let legacy = user.result.legacy;
-          reportParams.twitterFans = legacy ? legacy.followers_count : 0;
-
-          if (!discordTaskDetail) {
-            if (reportParams.hasReport) return;
-            reportParams.hasReport = true;
-            Report.reportLog({
-              objectType: Report.objectType.tweetPostBinded,
-              twitterFans: reportParams.twitterFans,
-              redPacketType: 0,
-              postId: state.postId
-            });
-          } else {
-            if (reportParams.discordFans !== '') {
-              if (reportParams.hasReport) return;
-              reportParams.hasReport = true;
-              Report.reportLog({
-                objectType: Report.objectType.tweetPostBinded,
-                twitterFans: reportParams.twitterFans,
-                discordFans: reportParams.discordFans,
-                redPacketType: 0,
-                postId: state.postId
-              });
-            }
-          }
-
-        }
-        break;
     }
     sendResponse && sendResponse();
   })
@@ -1964,10 +1949,6 @@ function discordAuth(actionState = 'default') {
           type: 'normal',
           url: authorizeUrl
         }, function (window) {
-          let windowId = window.id;
-          callEventPageMethod("RED_PACKET_SAVE_DISCORD_AUTH_WINDOW_ID", {
-            windowId: windowId
-          });
         })
       }
     }

+ 65 - 143
src/view/iframe/treasure-hunt/all-receive-list.vue

@@ -2,139 +2,60 @@
     <div class="invite-list">
         <div class="head">
             <div class="left">
-              <img height="20" :src="require('@/assets/svg/icon-back-2.svg')" @click="clickBack" />
-              <span>{{ state.detail.receiveCountWithAmount }} People Get Money</span>
+                <img height="20" :src="require('@/assets/svg/icon-back-2.svg')" @click="clickBack" />
+                <span>{{ state.detail.receiveCountWithAmount }} People Get Money</span>
             </div>
             <div class="right">
-              <img @click="showOptionSheet = true" :src="sortTypeIcon" alt="">
+                <img @click="clickOption" :src="sortTypeIcon" alt="">
             </div>
         </div>
-        <div class="content">
-            <img v-show="state.receive.loading && state.receive.list.length == 0"
-                :src="require('@/assets/svg/icon-loading-gray.svg')" alt="" class="loading" />
-            <img v-if="state.receive.list.length == 0 && state.receive.end"
-                :src="require('@/assets/svg/icon-empty-list.svg')" alt="" class="empty" />
-            <div class="list" v-else @scroll="handleScroll($event)">
-                <div class="item" v-for="item in state.receive.list" :key="item.userInfo.uid">
-                    <div class="left">
-                        <img :src="item.userInfo.avatarUrl" alt="" @click="clickItem(item)" />
-                    </div>
-                    <div class="right">
-                        <div>
-                            <div class="name" @click="clickItem(item)">{{ item.userInfo.nickName }}</div>
-                            <div class="time">{{ getBeforeTimeFormat(item.timestamp) }}</div>
-                        </div>
-                        <div class="money">${{ item.amountUsdValue }}</div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <div class="option-sheet" v-if="showOptionSheet">
-          <div class="item" v-for="(item, index) in optionList" :key="index" @click="clickOption(item)">
-            <img :src="item.icon" >
-            <div class="label">
-              {{item.label}}
-            </div>
-          </div>
-        </div>
-        <div class="option-mask" v-if="showOptionSheet" @click="showOptionSheet = false"></div>
+        <receive-list :sortType="sortType"></receive-list>
     </div>
 </template>
 <script setup>
-import { receiveListV2 } from '@/http/treasure'
-import { inject, onMounted, ref } from 'vue'
-import { getBeforeTimeFormat } from "@/uilts/help"
-import Report from "@/log-center/log"
+import { inject, ref } from 'vue'
+import ReceiveList from '@/view/iframe/treasure-hunt/components/receive-list.vue'
 
 let amountIcon = require('@/assets/svg/icon-sort-amount.svg');
 let timeIcon = require('@/assets/svg/icon-sort-time.svg');
 
-
 let sortTypeIcon = ref(amountIcon);
 
 let state = inject('state')
-state.receive = {
-    end: false,
-    list: []
-}
 
 let optionList = ref([
-  {
-    icon: amountIcon,
-    label: 'Amount',
-    type: 2
-  },
-  {
-    icon: timeIcon,
-    label: 'Time',
-    type: 1
-  }
+    {
+        icon: amountIcon,
+        label: 'Amount',
+        type: 2
+    },
+    {
+        icon: timeIcon,
+        label: 'Time',
+        type: 1
+    }
 ])
 
 
-let page_num = 1
-let page_size = 10
-let sortType = 2;
-let list_end = false
+let sortType = ref(2);
 
-let showOptionSheet = ref(false);
 
 const clickBack = () => {
     state.page_show = ''
 }
 
-onMounted(() => {
-    list()
-})
 
-const clickItem = (item) => {
-    window.open(`https://twitter.com/${item.userInfo.nickName}`)
-}
 
-const clickOption = (params) => {
-  showOptionSheet.value = false;
-  sortTypeIcon.value = params.icon;
-  page_num = 1;
-  sortType = params.type;
-  list()
-}
-
-function handleScroll(e) {
-    if (list_end) {
-        return
-    }
-    e = e.target
-    if ((e.clientHeight + e.scrollTop) / e.scrollHeight > .8) {
-        if (page_num * page_size == state.receive.list.length) {
-            page_num++
-            list()
-        }
-        list_end = true
+const clickOption = () => {
+    if (sortType.value == 1) {
+        sortType.value = 2
+    } else if (sortType.value == 2) {
+        sortType.value = 1
     }
+    // 切换图标
+    sortTypeIcon.value = optionList.value.filter((item) => { return item.type == sortType.value })[0].icon;
 }
 
-const list = () => {
-    state.receive.loading = true
-    receiveListV2({
-        params: {
-            postId: state.postId,
-            pageNum: page_num,
-            pageSize: page_size,
-            sortType
-        }
-    }).then((res) => {
-        if (res.code == 0) {
-            state.receive.loading = false
-            if(page_num < 2) {
-              state.receive.list = res.data || [];
-            } else {
-              state.receive.list = state.receive.list.concat(res.data)
-            }
-            state.receive.end = true
-            list_end = false
-        }
-    })
-}
 </script>
 <style lang="scss" scoped>
 .invite-list {
@@ -154,8 +75,8 @@ const list = () => {
         box-shadow: inset 0px -1px 0px #F2F2F2;
 
         .left {
-          display: flex;
-          align-items: center;
+            display: flex;
+            align-items: center;
         }
 
         img {
@@ -254,49 +175,50 @@ const list = () => {
     }
 
     .option-mask {
-      width: 100%;
-      height: 100%;
-      position: absolute;
-      top: 0;
-      left: 0;
-      z-index: 800;
-    }
-    .option-sheet {
-      width: 200px;
-      background: #FFFFFF;
-      box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.2);
-      border-radius: 14px;
-      position: absolute;
-      top: 40px;
-      right: 8px;
-      z-index: 1000;
-      cursor: pointer;
-
-      .item {
         width: 100%;
-        height: 40px;
-        display: flex;
-        align-items: center;
+        height: 100%;
+        position: absolute;
+        top: 0;
+        left: 0;
+        z-index: 800;
+    }
 
-        img {
-          width: 24px;
-          margin: 0 12px;
-        }
+    .option-sheet {
+        width: 200px;
+        background: #FFFFFF;
+        box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.2);
+        border-radius: 14px;
+        position: absolute;
+        top: 40px;
+        right: 8px;
+        z-index: 1000;
+        cursor: pointer;
+
+        .item {
+            width: 100%;
+            height: 40px;
+            display: flex;
+            align-items: center;
+
+            img {
+                width: 24px;
+                margin: 0 12px;
+            }
 
-        .label {
-          font-weight: 500;
-          font-size: 15px;
-          width: calc(100% - 52px);
-          height: 100%;
-          display: flex;
-          align-items: center;
+            .label {
+                font-weight: 500;
+                font-size: 15px;
+                width: calc(100% - 52px);
+                height: 100%;
+                display: flex;
+                align-items: center;
+            }
         }
-      }
 
-       .item:first-child {
-          .label {
-            box-shadow: inset 0px -1px 0px #F2F2F2;
-          }
+        .item:first-child {
+            .label {
+                box-shadow: inset 0px -1px 0px #F2F2F2;
+            }
         }
     }
 }

+ 8 - 8
src/view/iframe/treasure-hunt/components/boxs.vue

@@ -2,8 +2,7 @@
     <div class="area-boxs">
         <!-- 箱子 -->
         <div class="box-process">
-            <div class="item" v-for="item, i in state.boxs"
-                :key="i"
+            <div class="item" v-for="item, i in state.boxs" :key="i"
                 :style="{ 'margin-left': item.icon_margin_left, 'z-index': 10 - i }">
                 <!--悬浮 -->
                 <!-- < hover - tip : txt=" item.txt" v-show="item.show || item.openStatus" :icon="item.hover_icon">
@@ -16,10 +15,11 @@
                 <!-- 宝箱 -->
                 <img :src="item.icon" alt="" @mouseenter="mouseItem(i)" @mouseleave="mouseLeaveItem(i)"
                     :style="{ 'width': item.icon_width, 'height': item.icon_width }" class="box"
-                    :class="{ 'active': i == 0 && item.openStatus == 0 ? true : item.openStatus == 0 && state.boxs[i-1]['openStatus'] == 1  }" @click="clickBox(item)" />
+                    :class="{ 'active': i == 0 && item.openStatus == 0 ? true : item.openStatus == 0 && state.boxs[i - 1]['openStatus'] == 1 }"
+                    @click="clickBox(item)" />
                 <!-- 发光 -->
                 <img :src="require('@/assets/img/icon-flash-active.png')" alt="" class="flash"
-                    v-if="i == 0 && item.openStatus == 0 ? true : item.openStatus == 0 && state.boxs[i-1]['openStatus'] == 1"
+                    v-if="i == 0 && item.openStatus == 0 ? true : item.openStatus == 0 && state.boxs[i - 1]['openStatus'] == 1"
                     :style="{ 'margin-left': item.flash_margin_top, 'margin-top': item.flash_margin_top, 'width': item.flash_width, 'height': item.flash_width }" />
 
                 <!-- 进度条 -->
@@ -30,8 +30,7 @@
         </div>
         <!-- 人数 -->
         <div class="people">
-            <div class="item" v-for="item, i in state.boxs"
-            :key="i"
+            <div class="item" v-for="item, i in state.boxs" :key="i"
                 :style="{ 'margin-left': item.icon_margin_left, 'width': item.icon_width }">
                 <img :src="require('@/assets/svg/icon-user1.svg')" alt="" />
                 <span>{{ item.inviteProgress }}</span>
@@ -179,10 +178,11 @@ const btnStatus = () => {
 }
 
 
-
 const mouseItem = (i) => {
     state.boxs[i].show = true
-    state.active_share_channel = true
+    if (state.boxs[i].openStatus == 0) {
+        state.active_share_channel = true
+    }
 }
 const mouseLeaveItem = (i) => {
     state.boxs[i].show = false

+ 17 - 4
src/view/iframe/treasure-hunt/components/btn.vue

@@ -1,6 +1,7 @@
 <template>
     <div :class="{ 'area-btn': disabled }">
-        <div class="btn-submit" @click="clickBtn" :class="{ 'no': loading, 'disabled': disabled }">
+        <div class="btn-submit" @click="clickBtn" :class="{ 'no': loading, 'disabled': disabled }"
+            @mouseenter="mouseItem" @mouseleave="mouseLeaveItem">
             <img :src="require('@/assets/svg/icon-iframe-loading.svg')" alt="" class="loading" v-if="loading && icon" />
             <img :src="require('@/assets/svg/icon-btn-box.svg')" alt="" v-if="!loading && icon" />
             <span :style="{ 'font-size': fontSize, 'color': txtCorlor, 'font-weight': fontWeight }">{{ txt }}</span>
@@ -44,7 +45,19 @@ let props = defineProps({
         type: String
     }
 })
-const emit = defineEmits(['on-click'])
+const emit = defineEmits(['on-click', 'on-mouseEnter', 'on-mouseLeave'])
+
+const mouseItem = () => {
+    if (props.disabled) {
+        emit('on-mouseEnter')
+    }
+}
+
+const mouseLeaveItem = () => {
+    if (props.disabled) {
+        emit('on-mouseLeave')
+    }
+}
 
 const clickBtn = () => {
     if (props.disabled == false && props.loading == false) {
@@ -121,8 +134,8 @@ const refresh = () => {
     }
 
     .disabled {
-        cursor: no-drop;
-        background: rgba(56, 154, 255, 0.2);
+        cursor: default;
+        background: rgba(56, 154, 255, 0.4);
         color: #FFFFFF;
         width: 305px;
         font-weight: 600;

+ 1 - 0
src/view/iframe/treasure-hunt/components/carousel.vue

@@ -48,6 +48,7 @@ const init = () => {
             postId: state.postId,
             pageNum: 1,
             pageSize: 1000,
+            sortType: 2
         }
     }).then((res) => {
         if (res.code == 0) {

+ 300 - 265
src/view/iframe/treasure-hunt/components/invite-friends.vue

@@ -1,48 +1,56 @@
 <template>
-    <div class="invite-friends">
-      <div class="invite-friends-content">
-        <div class="invite-friends-content-head">
-          <div class="title">Invite Friends to Open the Chest!</div>
-          <div class="info">Invitees Need to be Real New follower of {{followUserStr}} to receive rewards</div>
+  <div class="invite-friends">
+    <div class="invite-friends-content">
+      <div class="invite-friends-content-head">
+        <div class="title">Invite Friends to Open the Chest!</div>
+        <div class="info">Invitees Need to be <span>Real New follower</span> of {{ followUserStr }} to receive rewards
         </div>
-        <div class="invite-friends-content-body">
+      </div>
+      <div class="invite-friends-content-body">
+        <template v-if="state.share_list_end">
           <img class="tips" v-if="state.active_share_channel" :src="require('@/assets/svg/icon-channel-tips.svg')" />
 
-          <div class="share-list" :class="{'share-list-active': state.active_share_channel}">
+          <div class="share-list" :class="{ 'share-list-active': state.active_share_channel }">
             <div v-for="(item, index) in state.share_list" :key="index" :data-clipboard-text="item.inviteContent"
-                @click="clickShare(item)" class="share-item">
-              <img :src="item.iconPath"  />
+              @click="clickShare(item)" class="share-item">
+              <img :src="item.iconPath" />
               <div class="name">
-                {{item.name}}
+                {{ item.name }}
               </div>
             </div>
-            <div class="share-item copy-btn" @click="clickCopy" v-click-log="state.log_invite_copy_btn_click"
-                :data-clipboard-text="state.detail.inviteCopyUrl">
+            <div v-show="state.share_list_end" class="share-item copy-btn" @click="clickCopy"
+              v-click-log="state.log_invite_copy_btn_click" :data-clipboard-text="state.detail.inviteCopyUrl">
               <img :src="require('@/assets/svg/icon-copy-url-teasure.svg')" alt="">
               <div class="name">
                 Copy URL
               </div>
             </div>
-        </div>
-        </div>
-      </div>
-      <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false"
-            :disabled="state.open_btn.disabled" v-show-log="state.log_invite_btn_show" :loading="state.btn_loading"
-            v-click-log="state.log_invite_btn_click" @onClick="clickBtn" font-weight="600"></v-btn>
-      <div class="mask" v-show="showShareTips">
-        <div class="content">
-          <img class="icon-loading" :src="channelLoadingImg" />
-          <div class="text">
-            Link copied to clipboard
-             <br/>
-            Opening {{selectShareApp.name }}
           </div>
+        </template>
+        <template v-else>
+          <v-loading></v-loading>
+        </template>
+      </div>
+    </div>
+    <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false" :disabled="state.open_btn.disabled"
+      v-show-log="state.log_invite_btn_show" :loading="state.btn_loading" @onClick="clickBtn" font-weight="600"
+      @onMouseEnter="mouseItem" @onMouseLeave="mouseLeave"></v-btn>
+
+    <div class="mask" v-show="showShareTips">
+      <div class="content">
+        <img class="icon-loading" :src="channelLoadingImg" />
+        <div class="text">
+          Link copied to clipboard
+          <br />
+          Opening {{ selectShareApp.name }}
         </div>
       </div>
     </div>
+  </div>
 </template>
 <script setup>
 import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+import VLoading from '@/view/components/loading.vue'
 import { inviteChannel } from '@/http/treasure'
 import { inject, onMounted, ref } from 'vue'
 import Report from "@/log-center/log"
@@ -58,40 +66,40 @@ let channelLoadingImg = ref(loadingImg);
 let state = inject('state')
 
 state.log_invite_btn_show = {
-    businessType: Report.businessType.buttonView,
-    pageSource: Report.pageSource.inviteFriendsPage,
-    objectType: Report.objectType.openChestButton,
-    redPacketType: Report.redPacketType.treasure,
-    shareLinkId: state.invite_code,
-    myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.inviteCount,
-    postId: state.postId
+  businessType: Report.businessType.buttonView,
+  pageSource: Report.pageSource.inviteFriendsPage,
+  objectType: Report.objectType.openChestButton,
+  redPacketType: Report.redPacketType.treasure,
+  shareLinkId: state.invite_code,
+  myShareLinkId: state.detail.inviteCopyUrl,
+  currentInvitedNum: state.inviteCount,
+  postId: state.postId
 }
 
 state.log_invite_btn_click = {
-    businessType: Report.businessType.buttonClick,
-    pageSource: Report.pageSource.inviteFriendsPage,
-    objectType: Report.objectType.openChestButton,
-    redPacketType: Report.redPacketType.treasure,
-    shareLinkId: state.invite_code,
-    myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.inviteCount,
-    postId: state.postId
+  businessType: Report.businessType.buttonClick,
+  pageSource: Report.pageSource.inviteFriendsPage,
+  objectType: Report.objectType.openChestButton,
+  redPacketType: Report.redPacketType.treasure,
+  shareLinkId: state.invite_code,
+  myShareLinkId: state.detail.inviteCopyUrl,
+  currentInvitedNum: state.inviteCount,
+  postId: state.postId
 }
 state.log_invite_copy_btn_click = {
-    businessType: Report.businessType.buttonClick,
-    pageSource: Report.pageSource.inviteFriendsPage,
-    objectType: Report.objectType.copyButton,
-    redPacketType: Report.redPacketType.treasure,
-    shareLinkId: state.invite_code,
-    myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.inviteCount,
-    postId: state.postId
+  businessType: Report.businessType.buttonClick,
+  pageSource: Report.pageSource.inviteFriendsPage,
+  objectType: Report.objectType.copyButton,
+  redPacketType: Report.redPacketType.treasure,
+  shareLinkId: state.invite_code,
+  myShareLinkId: state.detail.inviteCopyUrl,
+  currentInvitedNum: state.inviteCount,
+  postId: state.postId
 }
 
 let facebookAppConfig = {
-    facebookAppId: "",
-    faceShareRedirectUrl
+  facebookAppId: "",
+  faceShareRedirectUrl
 };
 
 let selectShareApp = ref({});
@@ -99,287 +107,314 @@ let showShareTips = ref(false);
 let followUserStr = ref('');
 
 onMounted(() => {
-    state.btn_loading = false
-    setFrontConfig();
-    initInviteChannel();
-    getFollowUserStr();
+  state.btn_loading = false
+  setFrontConfig();
+  initInviteChannel();
+  getFollowUserStr();
 })
 
+const mouseItem = () => {
+  if (state.boxs.filter((item) => { return item.openStatus == 0 }).length) {
+    state.active_share_channel = true
+  }
+}
+
+const mouseLeave = () => {
+  state.active_share_channel = false
+}
+
 const getFollowUserStr = () => {
   let arr = [];
-  if(state.follows && state.follows.length) {
-    for(let i = 0; i < state.follows.length; i++) {
+  if (state.follows && state.follows.length) {
+    for (let i = 0; i < state.follows.length; i++) {
       let item = state.follows[i];
-      arr.push('@'+item.name);
+      arr.push('@' + item.name);
     }
   }
   followUserStr.value = arr.join(" or ");
 }
 
 chrome.management.onDisabled.addListener(() => {
-    initInviteChannel()
+  initInviteChannel()
 })
 chrome.management.onEnabled.addListener(() => {
-    initInviteChannel()
+  initInviteChannel()
 })
 
 chrome.management.onInstalled.addListener(() => {
-    initInviteChannel()
+  initInviteChannel()
 })
 chrome.management.onUninstalled.addListener(() => {
-    initInviteChannel()
+  initInviteChannel()
 })
 
 let linePluginInstalled
 const initInviteChannel = () => {
-    try {
-        chrome.management.get('ophjlpahpchlmihnnnihgmmeilfjmjjc', (res) => {
-            if ((res && linePluginInstalled == 1) || (!res && linePluginInstalled == 0)) {
-                return
-            }
-            if (res) {
-                linePluginInstalled = 1
-            } else {
-                linePluginInstalled = 0
-            }
-
-            inviteChannel({
-                params: {
-                    linePluginInstalled,
-                    postId: state.postId
-                }
-            }).then((res) => {
-                if (res.code == 0) {
-                    state.share_list = res.data
-                }
-            })
-        })
-    } catch (error) {
-        console.error(error)
-    }
+  try {
+    chrome.management.get('ophjlpahpchlmihnnnihgmmeilfjmjjc', (res) => {
+      if ((res && linePluginInstalled == 1) || (!res && linePluginInstalled == 0)) {
+        return
+      }
+      if (res) {
+        linePluginInstalled = 1
+      } else {
+        linePluginInstalled = 0
+      }
+
+      inviteChannel({
+        params: {
+          linePluginInstalled,
+          postId: state.postId
+        }
+      }).then((res) => {
+        if (res.code == 0) {
+          state.share_list = res.data
+          state.share_list_end = true
+        }
+      })
+    })
+  } catch (error) {
+    console.error(error)
+  }
 }
 
 async function clickBtn() {
-    let _userInfo = await state.checkIsLogin()
-    if (!_userInfo) {
-        return
-    }
-    state.btn_loading = true
-    state.treasureOpen()
+  let _userInfo = await state.checkIsLogin()
+  if (!_userInfo) {
+    return
+  }
+  state.btn_loading = true
+  state.treasureOpen()
+  // 埋点
+  Report.reportLog(state.log_invite_btn_click)
 }
 
 const clickShare = (item) => {
-    channelLoadingImg.value = loadingImg;
-    var clipboard = new ClipboardJS('.share-item');
-    clipboard.on('success', function (e) {
-        // state.toast.txt = 'Copy Successfully'
-        // state.toast.has_icon = true
-        // state.toast.show = true
-        // setTimeout(() => {
-        //     state.toast.show = false
-        // }, 2000)
-        e.clearSelection();
+  channelLoadingImg.value = loadingImg;
+  var clipboard = new ClipboardJS('.share-item');
+  clipboard.on('success', function (e) {
+    // state.toast.txt = 'Copy Successfully'
+    // state.toast.has_icon = true
+    // state.toast.show = true
+    // setTimeout(() => {
+    //     state.toast.show = false
+    // }, 2000)
+    e.clearSelection();
+  })
+  showShareTips.value = true;
+  selectShareApp.value = item;
+
+  if (item.name == 'facebook') {
+    setChromeStorage({
+      shareFacebookData: JSON.stringify({
+        contentStr: item.inviteContent
+      })
     })
-    showShareTips.value = true;
-    selectShareApp.value = item;
-
-    if (item.name == 'facebook') {
-        setChromeStorage({
-            shareFacebookData: JSON.stringify({
-                contentStr: item.inviteContent
-            })
-        })
-        let cbParams = {
-            bizType: 'TEASURE_INVITE'
-        }
-        let url = `https://www.facebook.com/dialog/share?app_id=${facebookAppConfig.facebookAppId}&display=popup&href=${item.treasureInviteUrl}&redirect_uri=${facebookAppConfig.faceShareRedirectUrl}?params=${JSON.stringify(cbParams)}`;
-
-        setTimeout(() => {
-          showShareTips.value = false;
-          chrome.windows.create({
-            width: 800,
-              type: 'normal',
-              url
-          }, function (window) {
-          })
-        }, 1000)
-
-    } else {
-        setTimeout(() => {
-          showShareTips.value = false;
-          channelLoadingImg.value = '';
-          chrome.tabs.create({
-              url: item.redirectPath
-          });
-        }, 1000)
+    let cbParams = {
+      bizType: 'TEASURE_INVITE'
     }
-    Report.reportLog({
-        businessType: Report.businessType.buttonClick,
-        pageSource: Report.pageSource.inviteFriendsPage,
-        objectType: Report.objectType.channelButton,
-        shareLinkId: state.invite_code,
-        myShareLinkId: state.detail.inviteCopyUrl,
-        currentInvitedNum: state.inviteCount,
-        postId: state.postId,
-        redPacketType: Report.redPacketType.treasure
-    }, {
-        'channel-name': item.name
-    });
+    let url = `https://www.facebook.com/dialog/share?app_id=${facebookAppConfig.facebookAppId}&display=popup&href=${item.treasureInviteUrl}&redirect_uri=${facebookAppConfig.faceShareRedirectUrl}?params=${JSON.stringify(cbParams)}`;
+
+    setTimeout(() => {
+      showShareTips.value = false;
+      chrome.windows.create({
+        width: 800,
+        type: 'normal',
+        url
+      }, function (window) {
+      })
+    }, 1000)
+
+  } else {
+    setTimeout(() => {
+      showShareTips.value = false;
+      channelLoadingImg.value = '';
+      chrome.tabs.create({
+        url: item.redirectPath
+      });
+    }, 1000)
+  }
+  Report.reportLog({
+    businessType: Report.businessType.buttonClick,
+    pageSource: Report.pageSource.inviteFriendsPage,
+    objectType: Report.objectType.channelButton,
+    shareLinkId: state.invite_code,
+    myShareLinkId: state.detail.inviteCopyUrl,
+    currentInvitedNum: state.inviteCount,
+    postId: state.postId,
+    redPacketType: Report.redPacketType.treasure
+  }, {
+    'channel-name': item.name
+  });
 }
 
 const setFrontConfig = () => {
-    getFrontConfig({
-        params: {},
-    }).then((res) => {
-        if (res.code == 0) {
-            facebookAppConfig.facebookAppId = res.data.fbClientId;
-        }
-    });
+  getFrontConfig({
+    params: {},
+  }).then((res) => {
+    if (res.code == 0) {
+      facebookAppConfig.facebookAppId = res.data.fbClientId;
+    }
+  });
 };
 
 
 
 const clickCopy = () => {
-    var clipboard = new ClipboardJS('.copy-btn');
-    clipboard.on('success', function (e) {
-        state.toast.txt = 'Copy Successfully'
-        state.toast.has_icon = true
-        state.toast.show = true
-        setTimeout(() => {
-            state.toast.show = false
-        }, 2000)
-        e.clearSelection();
-    })
-
-    clipboard.on('error', function (e) {
-        state.toast.txt = 'Copy Error'
-        state.toast.has_icon = false
-        state.toast.show = true
-        setTimeout(() => {
-            state.toast.show = false
-        }, 2000)
-    })
+  var clipboard = new ClipboardJS('.copy-btn');
+  clipboard.on('success', function (e) {
+    state.toast.txt = 'Copy Successfully'
+    state.toast.has_icon = true
+    state.toast.show = true
+    setTimeout(() => {
+      state.toast.show = false
+    }, 2000)
+    e.clearSelection();
+  })
+
+  clipboard.on('error', function (e) {
+    state.toast.txt = 'Copy Error'
+    state.toast.has_icon = false
+    state.toast.show = true
+    setTimeout(() => {
+      state.toast.show = false
+    }, 2000)
+  })
 }
 </script>
 <style lang="scss" scoped>
 .invite-friends {
-    padding: 9px 14px 14px 14px;
-    background: #fff;
+  padding: 9px 14px 14px 14px;
+  background: #fff;
+  box-sizing: border-box;
+
+  .invite-friends-content {
+    max-height: 242px;
+    overflow-y: auto;
+    margin-bottom: 10px;
     box-sizing: border-box;
 
-    .invite-friends-content {
-      max-height: 242px;
-      overflow-y: auto;
-      margin-bottom: 10px;
+    .invite-friends-content-head {
+      margin-bottom: 16px;
+      padding: 0 6px;
       box-sizing: border-box;
 
-      .invite-friends-content-head {
-        margin-bottom: 16px;
-        padding: 0 6px;
-        box-sizing: border-box;
+      .title {
+        font-weight: 900;
+        font-size: 18px;
+        margin-bottom: 7px;
+      }
 
-        .title {
-          font-weight: 900;
-          font-size: 18px;
-          margin-bottom: 7px;
-        }
-        .info {
-          font-weight: 400;
+      .info {
+        font-weight: 400;
+        font-size: 12px;
+        color: #7A7A7A;
+        line-height: 15px;
+
+        span {
+          font-weight: 800;
           font-size: 12px;
-          color: #7A7A7A;
           line-height: 15px;
+          color: #000000;
         }
+      }
+
+    }
 
+    .invite-friends-content-body {
+      position: relative;
+      height: 159px;
+
+      .tips {
+        position: absolute;
+        top: -42px;
+        left: 0;
+        width: 146px;
       }
 
-      .invite-friends-content-body {
-        position: relative;
+      .share-list-active {
+        background: rgba(29, 155, 240, 0.1);
+        border: 1.5px solid #1D9BF0 !important;
+        border-radius: 10px;
+      }
 
-        .tips {
-          position: absolute;
-          top: -42px;
-          left: 0;
-          width: 146px;
-        }
+      .share-list {
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
+        box-sizing: border-box;
+        border: 1.5px solid #fff;
 
-        .share-list-active {
-          background: rgba(29, 155, 240, 0.1);
-          border: 1.5px solid #1D9BF0 !important;
-          border-radius: 10px;
-        }
-        .share-list {
+        .share-item {
+          user-select: none;
+          width: 20%;
           display: flex;
-          flex-wrap: wrap;
-          width: 100%;
+          flex-direction: column;
+          align-items: center;
+          justify-content: center;
+          padding: 8px 2px;
           box-sizing: border-box;
-          border: 1.5px solid #fff;
-
-          .share-item {
-            user-select: none;
-            width: 20%;
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            justify-content: center;
-            padding: 8px 2px;
-            box-sizing: border-box;
-            border-radius: 12px;
-
-
-            cursor: pointer;
-            img {
-                width: 40px;
-                height: 40px;
-                border-radius: 100px;
-                margin-bottom: 8px;
-            }
-            .name {
-              font-weight: 400;
-              font-size: 12px;
-              color: #898989;
-              width: 100%;
-              overflow: hidden;
-              text-overflow: ellipsis; //文本溢出显示省略号
-              white-space: nowrap;
-              text-align: center;
-            }
+          border-radius: 12px;
+
+
+          cursor: pointer;
+
+          img {
+            width: 40px;
+            height: 40px;
+            border-radius: 100px;
+            margin-bottom: 8px;
           }
 
-          .share-item:hover {
-            animation: fade-in-gray 0.25s linear forwards;
+          .name {
+            font-weight: 400;
+            font-size: 12px;
+            color: #898989;
+            width: 100%;
+            overflow: hidden;
+            text-overflow: ellipsis; //文本溢出显示省略号
+            white-space: nowrap;
+            text-align: center;
           }
+        }
 
+        .share-item:hover {
+          animation: fade-in-gray 0.25s linear forwards;
         }
+
       }
     }
-    .mask {
-      position: fixed;
-      top: 0;
-      left: 0;
-      width: 375px;
-      height: 100%;
-      background: rgba($color: #000000, $alpha: 0.9);
-      z-index: 1000;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-
-      .content {
-        text-align: center;
-      }
+  }
 
-      .icon-loading {
-        width: 60px;
-        height: 60px;
-        margin-bottom: 30px;
-      }
+  .mask {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 375px;
+    height: 100%;
+    background: rgba($color: #000000, $alpha: 0.9);
+    z-index: 1000;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    .content {
+      text-align: center;
+    }
 
-      .text {
-        font-weight: 600;
-        font-size: 17px;
-        color: #FFFFFF;
-      }
+    .icon-loading {
+      width: 60px;
+      height: 60px;
+      margin-bottom: 30px;
     }
+
+    .text {
+      font-weight: 600;
+      font-size: 17px;
+      color: #FFFFFF;
+    }
+  }
+
   @keyframes fade-in-gray {
     from {
       background: none;

+ 224 - 0
src/view/iframe/treasure-hunt/components/receive-list.vue

@@ -0,0 +1,224 @@
+<!-- 领取人列表组件 -->
+<template>
+    <div class="content">
+        <img v-show="receive.loading" :src="require('@/assets/svg/icon-loading-gray2.svg')" alt="" class="loading" />
+        <img v-if="receive.list.length == 0 && receive.end" :src="require('@/assets/svg/icon-empty-list.svg')" alt=""
+            class="empty" />
+        <div class="list" v-else @scroll="handleScroll($event)">
+            <div class="item" v-for="item in receive.list" :key="item.userInfo.uid">
+                <div class="left">
+                    <img :src="item.userInfo.avatarUrl" alt="" @click="clickItem(item)" />
+                </div>
+                <div class="right">
+                    <div>
+                        <div class="name" @click="clickItem(item)">{{ item.userInfo.nickName }}</div>
+                        <div class="time">{{ getBeforeTimeFormat(item.timestamp) }}</div>
+                    </div>
+                    <div>
+                        <div class="money">${{ item.amountUsdValue }}</div>
+                        <div class="count" :class="{ 'hide': Number(item.inviteNewFansCount) == 0 }">
+                            invited:{{ item.inviteNewFansCount }}</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script setup>
+import { receiveListV2 } from '@/http/treasure'
+import { onMounted, reactive, inject, defineProps, watch } from 'vue'
+import { getBeforeTimeFormat } from "@/uilts/help"
+let state = inject('state')
+let receive = reactive({
+    end: false,
+    list: []
+})
+let props = defineProps({
+    sortType: {
+        type: Number,
+        default: 2,
+    }
+})
+watch(props, () => {
+    sortType = props.sortType
+    page_num = 1
+    receive.loading = true
+    receive.list = []
+    receive.end = false
+    list()
+})
+let page_num = 1
+let page_size = 10
+let sortType = 2;
+let list_end = false
+onMounted(() => {
+    receive.loading = true
+    list()
+})
+
+const clickItem = (item) => {
+    window.open(`https://twitter.com/${item.userInfo.nickName}`)
+}
+
+function handleScroll(e) {
+    if (list_end) {
+        return
+    }
+    e = e.target
+    if ((e.clientHeight + e.scrollTop) / e.scrollHeight > .8) {
+        if (page_num * page_size == receive.list.length) {
+            page_num++
+            list()
+        }
+        list_end = true
+    }
+}
+
+const list = () => {
+    receiveListV2({
+        params: {
+            postId: state.postId,
+            pageNum: page_num,
+            pageSize: page_size,
+            sortType
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            receive.loading = false
+            if (page_num < 2) {
+                receive.list = res.data || [];
+            } else {
+                receive.list = receive.list.concat(res.data)
+            }
+            receive.end = true
+            list_end = false
+        }
+    })
+}
+</script>
+<style lang="scss" scoped>
+.content {
+    position: relative;
+    height: 100%;
+    overflow-y: auto;
+    background: #fff;
+
+    .footer {
+        background: #fff;
+        padding: 10px 16px 25px 16px;
+    }
+
+    .error {
+        height: 204px;
+        color: #BABABA;
+        background-color: #fff;
+        font-weight: 500;
+        font-size: 15px;
+        line-height: 204px;
+        text-align: center;
+
+    }
+
+    .list {
+        background: #fff;
+        overflow-y: auto;
+
+        .item {
+            height: 60px;
+            display: flex;
+            align-items: center;
+
+            .left {
+                width: 58px;
+                text-align: center;
+
+                img {
+                    cursor: pointer;
+                    border-radius: 50px;
+                    width: 30px;
+                    height: 30px;
+                }
+            }
+
+            .right {
+                flex: 1;
+                box-shadow: inset 0px -1px 0px #F2F2F2;
+
+                display: flex;
+                align-items: center;
+                height: 100%;
+                justify-content: space-between;
+
+                .name {
+                    color: #000000;
+                    font-weight: 500;
+                    font-size: 15px;
+                    cursor: pointer;
+                    margin-bottom: 5px;
+                }
+
+                .time {
+                    color: #A6A6A6;
+                    font-weight: 400;
+                    font-size: 12px;
+                    margin-right: 17px;
+                }
+
+                .money {
+                    color: #FCB936;
+                    font-weight: 500;
+                    font-size: 13px;
+                    margin-right: 16px;
+                    text-align: right;
+
+                }
+
+                .count {
+                    margin-right: 16px;
+                    color: #A9A9A9;
+                    font-weight: 400;
+                    font-size: 12px;
+                    text-align: right;
+                    margin-top: 5px;
+                }
+
+                .hide {
+                    visibility: hidden;
+
+                }
+            }
+        }
+    }
+}
+
+.loading {
+    width: 100px;
+    height: 100px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    margin-left: -50px;
+    margin-top: -50px;
+    animation: rotation 1s linear infinite;
+}
+
+.empty {
+    width: 100px;
+    height: 100px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    margin-left: -50px;
+    margin-top: -50px;
+}
+
+@keyframes rotation {
+    from {
+        -webkit-transform: rotate(0deg);
+    }
+
+    to {
+        -webkit-transform: rotate(360deg);
+    }
+}
+</style>

+ 140 - 15
src/view/iframe/treasure-hunt/cover.vue

@@ -1,6 +1,6 @@
 <template>
     <!-- 封面页 -->
-    <div class="cover" v-show-log="state.log_show">
+    <div class="cover">
         <v-head :left-data="state.detail.postUserInfo || null"></v-head>
         <div class="waring" v-if="state.cover_status == '奖励已被领光'">
             <div>All treasures</div>
@@ -50,7 +50,7 @@
 
 </template>
 <script setup>
-import { inject } from 'vue'
+import { inject, onMounted } from 'vue'
 import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
 import VHead from '@/view/iframe/treasure-hunt/components/head.vue'
 import ComponentZoom from "@/view/components/component-zoom.vue";
@@ -60,6 +60,7 @@ import { prepareStart, treasureStart } from '@/http/treasure.js'
 import { getChromeCookie, removeChromeCookie, getChromeStorage, sendCurrentTabMessage } from '@/uilts/chromeExtension.js'
 import { reSetBindRepost } from '@/http/help.js'
 import { guid } from '@/uilts/help.js'
+import { TaskType } from '@/types';
 
 let state = inject('state')
 let global_userInfo
@@ -107,7 +108,7 @@ const toStart = (req) => {
             })
             state.start_task = res.data
             if (req.response) {
-                let repost_tweetId = req.response.data.data.create_tweet.tweet_results.result.rest_id
+                let repost_tweetId = req.response.data.create_tweet.tweet_results.result.rest_id
                 reSetBindRepost({
                     inviteCode: res.data.inviteCode,
                     tweetId: repost_tweetId
@@ -121,7 +122,7 @@ const toStart = (req) => {
         console.error(error)
     })
 }
-
+/**
 chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     switch (req.actionType) {
         case 'DO_TASK':
@@ -229,7 +230,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
             break;
     }
 })
-
+ */
 const getFollowStatus = (arr = []) => {
     let list = [];
     let userInfoList = arr;
@@ -296,15 +297,26 @@ const logPreRepost = () => {
         })
     }
 
-    sendCurrentTabMessage({
+    window.parent.postMessage({
         actionType: "IFRAME_API_GET_TWEET_USER_FOLLOW_STATUS",
-        data: {
+        data: JSON.stringify({
             userList: names,
-            tweetId: state.tweetId
-        },
-        type: 'pre_repost',
+            tweetId: state.tweetId,
+            iframeGUId: state.iframeId,
+            type: 'pre_repost',
+        }),
         iframeId: state.iframeId
-    })
+    }, "*");
+
+    // sendCurrentTabMessage({
+    //     actionType: "IFRAME_API_GET_TWEET_USER_FOLLOW_STATUS",
+    //     data: {
+    //         userList: names,
+    //         tweetId: state.tweetId
+    //     },
+    //     type: 'pre_repost',
+    //     iframeId: state.iframeId
+    // })
     log_pre_repost.params = params
     log_pre_repost.names = names
 }
@@ -393,17 +405,130 @@ const getUsersFollowStatus = () => {
     let userList = state.follows;
 
     if (userList && userList.length) {
-        sendCurrentTabMessage({
+        window.parent.postMessage({
             actionType: "IFRAME_API_GET_TWEET_USER_FOLLOW_STATUS",
-            data: {
+            data: JSON.stringify({
                 userList: userList,
                 tweetId: state.tweetId,
-            },
+                iframeGUId: state.iframeId
+            }),
             iframeId: state.iframeId
-        })
+        }, "*");
     }
 }
 
+const onWindowMessage = () => {
+    window.onmessage = (res) => {
+        console.log('onWindowMessage', res);
+        let { info, data } = res.data
+        if (res && res.data && info) {
+            let msgData = data;
+            if (msgData.iframeGUId == state.iframeId) {
+                switch (info.actionType) {
+                    case "CONTENT_API_GET_TWEET_USER_INFO_END":
+                        let twitterFans = 0;
+                        let { user } = msgData.response || {};
+                        if (user && user.result && user.result.legacy) {
+                            let legacy = user.result.legacy;
+                            twitterFans = legacy ? legacy.followers_count : 0;
+                        }
+                        if (msgData.objectType == Report.objectType.repostSuccess) {
+                            Report.reportLog({
+                                objectType: Report.objectType.repostSuccess,
+                                twitterFans: twitterFans,
+                                redPacketType: Report.redPacketType.treasure,
+                                postId: state.postId,
+                                shareLinkId: state.invite_code,
+                            });
+                        };
+                        break;
+                    case "CONTENT_CREATE_TWEET_FINISH":
+                        if (!msgData.done) {
+                            state.toast.txt = 'Seems something went wrong, please try again'
+                            state.toast.show = true
+                            state.toast.has_icon = false
+                            setTimeout(() => {
+                                state.toast.show = false
+                            }, 2000)
+                        } else {
+                            toStart(msgData);
+                            getChromeStorage('userInfo', (_userInfo) => {
+                                if (_userInfo) {
+                                    window.parent.postMessage({
+                                        actionType: "IFRAME_API_GET_TWEET_USER_INFO_START",
+                                        data: JSON.stringify({
+                                            screen_name: _userInfo.nickName,
+                                            tweetId: state.tweetId,
+                                            objectType: Report.objectType.repostSuccess,
+                                            iframeGUId: state.iframeId,
+                                            iframeMsg: true
+                                        }),
+                                        iframeId: state.iframeId
+                                    }, "*");
+                                }
+                            })
+                        }
+
+                        break;
+                    case "CONTENT_GET_TWEET_USER_FOLLOW_STATUS_RES":
+                        state.usersFollowStatusList = getFollowStatus(msgData.list);
+                        // 上报埋点
+                        // 做任务
+                        // 一键三连
+                        let taskList = tasksDataHandler();
+                        window.parent.postMessage({
+                            actionType: "IFRAME_TWITTER_API_DO_TASK",
+                            data: JSON.stringify({
+                                tweet_Id: state.tweetId,
+                                tweet_text: state.rePostTweetContent,
+                                task_type: 'tasks',
+                                tasks: taskList,
+                                iframeGUId: state.iframeId
+                            }),
+                            iframeId: state.iframeId
+                        }, "*");
+
+                        // double like
+                        window.parent.postMessage({
+                            actionType: "IFRAME_TWITTER_API_DO_TASK",
+                            data: JSON.stringify({
+                                tweet_Id: state.detail.srcContentId,
+                                task_type: 'like',
+                                iframeGUId: state.iframeId
+                            }),
+                            iframeId: state.iframeId
+                        }, "*");
+                        break;
+                }
+            }
+        }
+    }
+}
+
+const tasksDataHandler = () => {
+  let data = state.tasks;
+  for(let i = 0; i < data.length; i++) {
+    if(data[i]['type'] == TaskType.twitterFollow) {
+      data[i]['relatedUsers'] = data[i]['relatedUsers'].filter(item => item.name != global_userInfo.nickName);
+      break;
+    }
+  }
+  return data;
+}
+
+onMounted(() => {
+    onWindowMessage()
+    // 埋点
+    Report.reportLog({
+        pageSource: Report.pageSource.pending_page,
+        businessType: Report.businessType.pageView,
+        postId: state.postId,
+        shareLinkId: state.invite_code,
+        currentInvitedNum: state.inviteCount,
+        redPacketType: Report.redPacketType.treasure
+    });
+})
+
 </script>
 <style lang="scss" scoped>
 .cover {

+ 72 - 23
src/view/iframe/treasure-hunt/index.vue

@@ -1,7 +1,7 @@
 <template>
     <v-cover v-if="state.page == '封面页'"></v-cover>
     <v-invite v-if="state.page == '邀请页'"></v-invite>
-    <v-result v-if="state.page == '开奖页'"></v-result>
+    <v-result v-if="state.page == '结果页'"></v-result>
 
     <open-box v-show="state.open_box.show"></open-box>
     <v-toast :show="state.toast.show" :txt="state.toast.txt" :has_icon="state.toast.has_icon"></v-toast>
@@ -63,8 +63,8 @@ onMounted(() => {
     state.page_type = params.page_type || ''
 
     state.init();
-    onRuntimeMsg();
-    // doLike()
+    // onRuntimeMsg();
+    onWindowMessage();
 })
 // denet
 // chrome
@@ -77,6 +77,44 @@ async function doLike() {
     }
 }
 
+const onWindowMessage = () => {
+    window.onmessage = (res) => {
+        console.log('onWindowMessage', res);
+        let { info, data } = res.data
+        if (res && res.data && info) {
+            let msgData = data;
+            if (msgData.iframeGUId == state.iframeId) {
+                switch (info.actionType) {
+                    case "CONTENT_GET_TWEET_TXT":
+                        if (msgData.tweet_Id == state.tweetId && !state.detail.postSrcContent) {
+                            state.detail.postSrcContent = msgData.txt
+                            reSetBindPostContent({
+                                postId: state.postId || '',
+                                postSrcContent: msgData.txt,
+                            })
+                        }
+                        break;
+                    case "CONTENT_API_GET_TWEET_USER_INFO_END":
+                        let twitterFans = 0;
+                        let { user } = msgData.response || {};
+                        if (user && user.result && user.result.legacy) {
+                            let legacy = user.result.legacy;
+                            twitterFans = legacy ? legacy.followers_count : 0;
+                        }
+                        if (msgData.objectType == Report.objectType.tweetPostBinded) {
+                            Report.reportLog({
+                                objectType: Report.objectType.tweetPostBinded,
+                                twitterFans: twitterFans,
+                                redPacketType: Report.redPacketType.treasure,
+                                postId: state.postId
+                            });
+                        }
+                        break;
+                }
+            }
+        }
+    }
+}
 state.checkIsLogin = () => {
     return new Promise((resolve) => {
         getChromeStorage('userInfo', (_userInfo) => {
@@ -127,12 +165,21 @@ state.init = (callback) => {
                 handleCommon(res, callback)
                 // 原始链接绑定post content
                 if (!res.data.postSrcContent) {
-                    sendCurrentTabMessage({
+
+                    window.parent.postMessage({
                         actionType: "GET_CONTENT_BY_TWITTER_ID",
-                        data: {
-                            tweet_Id: state.tweetId
-                        }
-                    })
+                        data: JSON.stringify({
+                            tweet_Id: state.tweetId,
+                            iframeGUId: state.iframeId,
+                        }),
+                        iframeId: state.iframeId
+                    }, "*");
+                    // sendCurrentTabMessage({
+                    //     actionType: "GET_CONTENT_BY_TWITTER_ID",
+                    //     data: {
+                    //         tweet_Id: state.tweetId
+                    //     }
+                    // })
                 }
             }
         })
@@ -186,15 +233,17 @@ const handleCommon = (res, callback) => {
             postId: state.postId || '',
             tweetId: state.tweetId || ''
         }, () => {
-            sendCurrentTabMessage({
-                actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
-                data: {
+            window.parent.postMessage({
+                actionType: "IFRAME_API_GET_TWEET_USER_INFO_START",
+                data: JSON.stringify({
                     screen_name: state.detail.postUserInfo.nickName,
                     tweetId: state.tweetId,
                     objectType: Report.objectType.tweetPostBinded,
-                    iframeId: state.iframeId
-                }
-            })
+                    iframeGUId: state.iframeId,
+                    iframeMsg: true
+                }),
+                iframeId: state.iframeId
+            }, "*");
             state.init()
         })
     }
@@ -308,17 +357,17 @@ const handleStatus = (callback) => {
     // 如果 夺宝状态 = 已结束
     else {
         state.open_btn.txt = 'Look for more treasures'
-        state.page = '封面页'
-        state.cover_status = '奖励已被领光'
+        state.page = '结果页'
+        // state.cover_status = '奖励已被领光'
         state.btn_loading = false
         Report.reportLog({
-          pageSource: Report.pageSource.expiredPage,
-          businessType: Report.businessType.pageView,
-          postId: state.postId,
-          shareLinkId: state.invite_code,
-          myShareLinkId: state.detail.inviteCopyUrl,
-          currentInvitedNum: state.inviteCount,
-          redPacketType: Report.redPacketType.treasure
+            pageSource: Report.pageSource.expiredPage,
+            businessType: Report.businessType.pageView,
+            postId: state.postId,
+            shareLinkId: state.invite_code,
+            myShareLinkId: state.detail.inviteCopyUrl,
+            currentInvitedNum: state.inviteCount,
+            redPacketType: Report.redPacketType.treasure
         });
         return
     }

+ 2 - 1
src/view/iframe/treasure-hunt/invite.vue

@@ -3,7 +3,7 @@
     <all-receive-list v-if="state.page_show == '总邀请者页'"></all-receive-list>
     <div v-show="state.page_show != '总邀请者页'">
         <!-- 邀请页 -->
-        <div class="area-process" v-show-log="state.log_invite_show">
+        <div class="area-process">
             <div class="area1">
                 <v-head :left-data="state.detail.postUserInfo || null" :rightData="state.detail.remainAmountUsdValue">
                 </v-head>
@@ -57,6 +57,7 @@ state.tabs = [{
 }]
 
 onMounted(() => {
+    Report.reportLog(state.log_invite_show)
     if (state.timer) {
         return
     }

+ 168 - 120
src/view/iframe/treasure-hunt/result.vue

@@ -1,168 +1,216 @@
 <template>
-    <!-- 开奖页 -->
-    <div class="content" v-show-log="state.log_result_show">
-        <img :src="require('@/assets/img/icon-silver-open-box-big.png')" alt="" />
-        <div class="mark">
-
-            <!-- 新粉 -->
-            <template v-if="Number(state.start_task.amountValue) > 0">
-                <p>You are now following
-                    <template v-for="item, i in state.follows">
-                        <span v-if="i == 0">@{{ item.name }}</span>
-                        <span v-else>, @{{ item.name }}</span>
-                    </template>
-                </p>
-                <p>You Win</p>
-                <component-zoom width="335" fontSize="34" style="margin:0 auto;">
-                    <div class="money">${{ state.start_task.usdAmountValue }}</div>
-                </component-zoom>
-                <div class="mark2">
-                    <img :src="state.start_task.currencyIcon" alt="" />
-                    <div>{{ state.start_task.amountValue }} {{ state.start_task.currencySymbol }} stored in your DeNet
-                        account</div>
+    <div class="content">
+        <!-- 结果页 -->
+        <div class="header">
+            <img :src="require('@/assets/subject/004-back-head-top.svg')" alt class="back" />
+            <!-- 领到钱了 -->
+            <template v-if="Number(state.detail.amountUsdValue) > 0">
+                <div class="tip1">This Giveaway Expired on {{ moment(state.detail.endTimestamp).format('MM-DD') }}</div>
+                <div class="tip2">🎉 Awesome! You are the Winner!</div>
+                <div class="tip3">+${{ state.detail.amountUsdValue }}</div>
+                <div class="tip3-back"></div>
+            </template>
+            <!-- 没有领到钱 -->
+            <template v-else>
+                <div class="rabbit">
+                    <img :src="require('@/assets/subject/001-icon-rabbit.svg')" alt />
+                    <p>Sorry, you missed this treasure</p>
+                </div>
+            </template>
+
+        </div>
+        <div class="list">
+            <receive-list></receive-list>
+        </div>
+        <div class="footer">
+            <!-- 领取到钱了 -->
+            <template v-if="Number(state.detail.amountUsdValue) > 0">
+                <div class="btn btn1" @click="clickDone">
+                    <img :src="require('@/assets/svg/icon-wallet-success.svg')" alt />
+                    <span>Wallet</span>
                 </div>
+                <get-more :style_type="4">
+                    <div class="btn btn2">
+                        <img :src="require('@/assets/svg/icon-gold-box-close.svg')" alt />
+                        <span>Get More</span>
+                    </div>
+                </get-more>
             </template>
-            <!-- 老粉不给钱 -->
+            <!-- 没有领到钱 -->
             <template v-else>
-                <p>You already followed
-                    <template v-for="item, i in state.follows">
-                        <span v-if="i == 0">@{{ item.name }}</span>
-                        <span v-else>, @{{ item.name }}</span>
-                    </template>
-                </p>
-                <p>Only new followers open silver chest</p>
-                <p class="txt">Invite people to</p>
-                <p class="txt">open golden chest!</p>
+                <div class="btn btn2 btn3" @click="clickBtn">
+                    <img :src="require('@/assets/svg/icon-gold-box-close.svg')" alt />
+                    <span>Look for more treasures</span>
+                </div>
             </template>
         </div>
-        <v-btn :txt="'Invite friends for more treasures'" :font-size="'16px'" class="btn"
-            v-if="Number(state.start_task.amountValue) > 0" v-click-log="state.log_result_click" @onClick="clickBtn"
-            :disabled="false"></v-btn>
-        <v-btn :txt="'Invite'" :font-size="'16px'" class="btn" v-else @onClick="clickBtn" :disabled="false"
-            v-click-log="state.log_result_click"></v-btn>
     </div>
 </template>
 <script setup>
 import { inject, onMounted } from 'vue'
-import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+import ReceiveList from '@/view/iframe/treasure-hunt/components/receive-list.vue'
+import { chromeExtensionUrl } from '@/uilts/chromeExtension.js'
+import GetMore from '@/view/iframe/publish/components/get-more.vue'
 import Report from "@/log-center/log"
 
 let state = inject('state')
+var moment = require('moment')
 
-state.log_result_show = {
-    businessType: Report.businessType.pageView,
-    pageSource: Report.pageSource.newFansRewardPage,
-    redPacketType: Report.redPacketType.treasure,
-    shareLinkId: state.invite_code,
-    postId: state.postId,
-    extParams: {
-        isNewFans: Number(state.start_task.amountValue) > 0 ? true : false
-    }
-}
-
-state.log_result_click = {
-    businessType: Report.businessType.buttonClick,
-    pageSource: Report.pageSource.newFansRewardPage,
-    objectType: Report.objectType.nextButton,
-    redPacketType: Report.redPacketType.treasure,
-    shareLinkId: state.invite_code,
-    postId: state.postId,
-    extParams: {
-        isNewFans: Number(state.start_task.amountValue) > 0 ? true : false
-    }
+function clickDone() {
+    window.open(`${chromeExtensionUrl + ('iframe/home.html')}`)
 }
 
-async function clickBtn() {
-    let _userInfo = await state.checkIsLogin()
-    if (!_userInfo) {
-        return
-    }
-    state.init(() => {
-        state.page = '邀请页'
-    })
+const clickBtn = () => {
+    // Report.reportLog({
+    //     pageSource: Report.pageSource.pending_page,
+    //     businessType: Report.businessType.buttonClick,
+    //     objectType: Report.objectType.getMoreGiveaway,
+    //     postId: state.postId
+    // });
+    window.open('https://twitter.com/search?q=%23denet');
 }
-JSON.parse('[{\"type\":2},{\"type\":10},{\"relatedUsers\":[{\"name\":\"Ice17619765\",\"twitterUserId\":\"1502254505236525056\"},{\"name\":\"IanDuddyUK\",\"twitterUserId\":\"556285604\"},{\"name\":\"ffvc\",\"twitterUserId\":\"285917234\"}],\"type\":1}]')
-
 </script>
 <style lang="scss" scoped>
 .content {
     width: 375px;
-    height: 500px;
-    background: linear-gradient(179.96deg, #876635 20.15%, #31251A 44.61%, #24180C 78.18%);
-    text-align: center;
-    position: relative;
-
-    img {
-        margin-top: 15px;
-        width: 250px;
-        height: 250px;
-    }
+    background: #fff;
 
-    .mark {
-        position: absolute;
-        top: 246px;
-        width: 375px;
-
-        p {
-            margin: 0;
-            padding: 0 16px;
-            text-align: center;
+    .header {
+        width: 100%;
+        min-height: 150px;
+        position: relative;
 
+        .back {
+            position: absolute;
+            top: 0;
+            left: 0;
         }
 
-        p:nth-child(1) {
-            color: #A9A49F;
-            font-weight: 400;
-            font-size: 12px;
-            margin-bottom: 10px;
+        .tip1 {
+            color: #FFFFFF;
+            opacity: 0.5;
+            text-align: center;
+            padding-top: 16px;
+            font-weight: 700;
+            font-size: 13px;
+            width: 100%;
+            z-index: 12;
+            width: 100%;
         }
 
-        p:nth-child(2) {
-            margin-bottom: 10px;
+        .tip2 {
             color: #FFFFFF;
+            text-align: center;
             font-weight: 800;
-            font-size: 18px;
-        }
+            width: 100%;
+            position: absolute;
+            font-size: 16px;
+            margin-top: 11px;
 
-        .txt {
-            color: #FFC83A;
-            font-weight: 800;
-            font-size: 24px;
+        }
 
+        .tip3-back {
+            width: 100%;
+            height: 43px;
+            position: absolute;
+            top: 74px;
+            left: 0;
+            background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.826667) 26.4%, #FFFFFF 71.47%, rgba(255, 255, 255, 0) 100%);
+            opacity: 0.15;
+            z-index: 1;
         }
 
-        .money {
-            color: #FFC83A;
+        .tip3 {
+            position: absolute;
+            top: 74px;
+            z-index: 2;
+            left: 0;
+            width: 100%;
+            line-height: 43px;
+            height: 43px;
+            color: #F5C03F;
+            text-align: center;
+            font-size: 26px;
             font-weight: 800;
-            font-size: 34px;
         }
 
-        .mark2 {
-            margin-top: 10px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
+
+        .rabbit {
+            width: 100%;
+            height: 100%;
+            text-align: center;
+            position: absolute;
+            z-index: 11;
 
             img {
-                width: 17px;
-                height: 17px;
-                margin: 0;
-                margin-right: 5px;
+                width: 150px;
+                height: 80px;
+                margin-top: 14px;
+                margin-bottom: 4px;
             }
 
-            div {
-                color: #A9A49F;
-                font-weight: 400;
-                font-size: 12px;
+            .flower {
+                width: 62px;
+                height: 62px;
+            }
 
+            p {
+                width: 100%;
+                margin: 0;
+                padding: 0;
+                font-weight: 800;
+                font-size: 16px;
+                color: #fff;
+                text-align: center;
+                letter-spacing: 0.3px;
             }
         }
     }
 
-    .btn {
-        position: absolute;
-        bottom: 25px;
-        left: 15px;
+    .list {
+        height: 336px;
+        margin-top: 10px;
+    }
+
+    .footer {
+        height: 84px;
+        display: flex;
+        padding: 16px;
+        justify-content: space-between;
+
+        .btn {
+            width: 166.5px;
+            height: 52px;
+            border-radius: 100px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-weight: 800;
+            font-size: 18px;
+            user-select: none;
+            cursor: pointer;
+
+            img {
+                width: 24px;
+                height: 24px;
+                margin-right: 7px;
+            }
+        }
+
+        .btn1 {
+            background: #FFFFFF;
+            border: 1px solid #DEDEDE;
+            color: #585858;
+        }
+
+        .btn2 {
+            color: #FFFFFF;
+            background: #1D9BF0;
+        }
+
+        .btn3 {
+            width: 100%;
+        }
     }
 }
 </style>

部分文件因文件數量過多而無法顯示