Преглед изворни кода

Merge branch 'dev_1.1.7.2' into feature_v1.1.8_220816

wenliming пре 2 година
родитељ
комит
bfc70b956d
86 измењених фајлова са 3598 додато и 1494 уклоњено
  1. 1 0
      package.json
  2. BIN
      src/assets/img/icon-gold-close-box.png
  3. BIN
      src/assets/img/icon-gold-open-box-big.png
  4. BIN
      src/assets/img/icon-gold-open-box.png
  5. BIN
      src/assets/img/icon-loading-channel.png
  6. BIN
      src/assets/img/icon-loading-redbag.png
  7. BIN
      src/assets/img/icon-purple-close-box.png
  8. BIN
      src/assets/img/icon-purple-open-big.png
  9. BIN
      src/assets/img/icon-purple-open-box.png
  10. BIN
      src/assets/img/icon-silver-close-box.png
  11. BIN
      src/assets/img/icon-silver-open-box-big.png
  12. BIN
      src/assets/img/icon-silver-open-box.png
  13. 3 0
      src/assets/svg/icon-back-2.svg
  14. 2 0
      src/assets/svg/icon-channel-tips.svg
  15. 16 0
      src/assets/svg/icon-copy-url-teasure.svg
  16. 13 0
      src/assets/svg/icon-invited-more.svg
  17. 4 0
      src/assets/svg/icon-loading-channel.svg
  18. 1 1
      src/assets/svg/icon-refresh-treasure.svg
  19. 4 0
      src/assets/svg/icon-sort-amount.svg
  20. 4 0
      src/assets/svg/icon-sort-time.svg
  21. 0 1
      src/assets/svg/icon-three-line.svg
  22. 5 0
      src/assets/svg/icon-user1.svg
  23. 1 1
      src/assets/svg/icon-while-yes.svg
  24. 4 5
      src/entry/background.js
  25. 19 2
      src/entry/content.js
  26. 8 2
      src/http/fetch.js
  27. 16 1
      src/http/help.js
  28. 14 2
      src/http/request.js
  29. 17 1
      src/http/toolBoxApi.js
  30. 29 2
      src/http/treasure.js
  31. 12 7
      src/log-center/logEnum.js
  32. 16 14
      src/logic/background/facebook.js
  33. 29 19
      src/logic/background/twitter.js
  34. 112 38
      src/logic/content/ParseCard.js
  35. 6 4
      src/logic/content/ToolBox.js
  36. 2 2
      src/logic/content/facebook.js
  37. 41 2
      src/logic/content/help/twitter.js
  38. 38 38
      src/logic/content/nft.js
  39. 229 93
      src/logic/content/twitter.js
  40. 2 2
      src/manifest.json
  41. 2 1
      src/uilts/chromeExtension.js
  42. 6 0
      src/uilts/denet.js
  43. 55 0
      src/uilts/help.js
  44. 9 9
      src/uilts/messageCenter/index.js
  45. 39 0
      src/uilts/messageCenter/messageContent.js
  46. 25 0
      src/uilts/messageCenter/messageEnum.js
  47. 12 1
      src/view/components/currency-list.vue
  48. 6 5
      src/view/components/custom-card-cover.vue
  49. 20 8
      src/view/components/custom-card-horizontal-cover.vue
  50. 12 9
      src/view/content/message/index.vue
  51. 27 18
      src/view/iframe/buy-nft/buy/home.vue
  52. 28 29
      src/view/iframe/buy-nft/buy/pay.vue
  53. 2 2
      src/view/iframe/buy-nft/group/tip.vue
  54. 11 11
      src/view/iframe/group-card/card.vue
  55. 18 0
      src/view/iframe/nft/card.vue
  56. 2 1
      src/view/iframe/publish/components/get-more.vue
  57. 13 21
      src/view/iframe/publish/components/give-dialog-head.vue
  58. 4 4
      src/view/iframe/publish/components/giveaway-poster.vue
  59. 1 1
      src/view/iframe/publish/components/nft-setting.vue
  60. 22 22
      src/view/iframe/publish/components/pay-button.vue
  61. 3 2
      src/view/iframe/publish/components/preview-card.vue
  62. 80 16
      src/view/iframe/publish/give-dialog.vue
  63. 55 77
      src/view/iframe/publish/tool-box/child/editor.vue
  64. 105 12
      src/view/iframe/publish/tool-box/child/preview.vue
  65. 90 5
      src/view/iframe/publish/tool-box/index.vue
  66. 25 22
      src/view/iframe/red-packet/luck-draw.vue
  67. 26 20
      src/view/iframe/red-packet/red-packet.vue
  68. 21 19
      src/view/iframe/tab-group/joined-group-list.vue
  69. 24 17
      src/view/iframe/tool-box/buy-nft.vue
  70. 24 18
      src/view/iframe/tool-box/card.vue
  71. 14 10
      src/view/iframe/tool-box/full.vue
  72. 334 0
      src/view/iframe/treasure-hunt/all-receive-list.vue
  73. 336 0
      src/view/iframe/treasure-hunt/components/boxs.vue
  74. 3 6
      src/view/iframe/treasure-hunt/components/btn.vue
  75. 191 0
      src/view/iframe/treasure-hunt/components/carousel.vue
  76. 2 2
      src/view/iframe/treasure-hunt/components/dialog.vue
  77. 3 2
      src/view/iframe/treasure-hunt/components/head.vue
  78. 262 96
      src/view/iframe/treasure-hunt/components/invite-friends.vue
  79. 86 0
      src/view/iframe/treasure-hunt/components/invite-layer.vue
  80. 390 159
      src/view/iframe/treasure-hunt/components/invite-list.vue
  81. 3 3
      src/view/iframe/treasure-hunt/components/open-box.vue
  82. 243 63
      src/view/iframe/treasure-hunt/cover.vue
  83. 103 24
      src/view/iframe/treasure-hunt/index.vue
  84. 30 353
      src/view/iframe/treasure-hunt/invite.vue
  85. 178 187
      src/view/popup/currency-detail.vue
  86. 5 2
      src/view/popup/tabbar-page/wallter/popup.vue

+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "build-watch": "vue-cli-service  --env.NODE_ENV=development build-watch --mode development"
   },
   "dependencies": {
+    "@fingerprintjs/fingerprintjs": "^3.3.5",
     "@sentry/tracing": "^7.5.1",
     "@sentry/vue": "^7.5.1",
     "ant-design-vue": "^2.2.8",

BIN
src/assets/img/icon-gold-close-box.png


BIN
src/assets/img/icon-gold-open-box-big.png


BIN
src/assets/img/icon-gold-open-box.png


BIN
src/assets/img/icon-loading-channel.png


BIN
src/assets/img/icon-loading-redbag.png


BIN
src/assets/img/icon-purple-close-box.png


BIN
src/assets/img/icon-purple-open-big.png


BIN
src/assets/img/icon-purple-open-box.png


BIN
src/assets/img/icon-silver-close-box.png


BIN
src/assets/img/icon-silver-open-box-big.png


BIN
src/assets/img/icon-silver-open-box.png


+ 3 - 0
src/assets/svg/icon-back-2.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M20.1427 11.3184V13.3184H8.14273L13.6427 18.8184L12.2227 20.2384L4.30273 12.3184L12.2227 4.39844L13.6427 5.81844L8.14273 11.3184H20.1427Z" fill="black"/>
+</svg>

Разлика између датотеке није приказан због своје велике величине
+ 2 - 0
src/assets/svg/icon-channel-tips.svg


+ 16 - 0
src/assets/svg/icon-copy-url-teasure.svg

@@ -0,0 +1,16 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_27199_78278)">
+<rect width="40" height="40" fill="#1D9BF0"/>
+<g clip-path="url(#clip1_27199_78278)">
+<path d="M27.7853 11.4827L27.7101 11.4075C25.9539 9.65127 23.0801 9.65127 21.3239 11.4075L17.2551 15.4763C15.4988 17.2326 15.4988 20.1057 17.2551 21.862L17.3303 21.9372C17.4765 22.0834 17.6318 22.2154 17.7917 22.3377L19.2811 20.8483C19.1074 20.7457 18.9433 20.6233 18.794 20.474L18.7188 20.3988C17.7655 19.4455 17.7655 17.894 18.7188 16.9407L22.7876 12.8712C23.741 11.9179 25.2925 11.9179 26.2458 12.8712L26.321 12.9465C27.2743 13.8998 27.2743 15.4519 26.321 16.4046L24.48 18.2456C24.7994 19.0348 24.951 19.8759 24.9379 20.7152L27.7847 17.8683C29.541 16.1121 29.541 13.2384 27.7853 11.4827ZM21.7716 17.3454C21.6254 17.1992 21.4702 17.0672 21.3102 16.9454L19.8208 18.4348C19.9945 18.5375 20.1587 18.6599 20.3079 18.8091L20.3831 18.8844C21.3364 19.8377 21.3364 21.3892 20.3831 22.3425L16.3143 26.4119C15.3609 27.3653 13.8095 27.3653 12.8561 26.4119L12.7809 26.3367C11.8276 25.3834 11.8276 23.8319 12.7809 22.8786L14.6219 21.0376C14.3025 20.2484 14.1509 19.4073 14.164 18.568L11.3172 21.4148C9.56094 23.1711 9.56094 26.0448 11.3172 27.801L11.3924 27.8763C13.1486 29.6325 16.0224 29.6325 17.7786 27.8763L21.8474 23.8074C23.6037 22.0512 23.6037 19.1775 21.8474 17.4212L21.7716 17.3454Z" fill="white"/>
+</g>
+</g>
+<defs>
+<clipPath id="clip0_27199_78278">
+<rect width="40" height="40" rx="20" fill="white"/>
+</clipPath>
+<clipPath id="clip1_27199_78278">
+<rect width="20" height="20" fill="white" transform="translate(10 10.0801)"/>
+</clipPath>
+</defs>
+</svg>

+ 13 - 0
src/assets/svg/icon-invited-more.svg

@@ -0,0 +1,13 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_27248_33494)">
+<circle opacity="0.2" cx="8" cy="8" r="8" fill="white"/>
+<ellipse cx="4.66406" cy="8" rx="1" ry="1" fill="white"/>
+<circle cx="8" cy="8" r="1" fill="white"/>
+<ellipse cx="11.3281" cy="8" rx="1" ry="1" fill="white"/>
+</g>
+<defs>
+<clipPath id="clip0_27248_33494">
+<rect width="16" height="16" rx="8" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 4 - 0
src/assets/svg/icon-loading-channel.svg

@@ -0,0 +1,4 @@
+<svg width="66" height="66" viewBox="0 0 66 66" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="33" cy="33" r="30" stroke="#424242" stroke-width="5"/>
+<path d="M63 33C63 16.4315 49.5685 3 33 3" stroke="#1D9BF0" stroke-width="5"/>
+</svg>

+ 1 - 1
src/assets/svg/icon-refresh-treasure.svg

@@ -1,3 +1,3 @@
 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M17.65 6.35C16.2 4.9 14.21 4 12 4C9.87827 4 7.84344 4.84285 6.34315 6.34315C4.84285 7.84344 4 9.87827 4 12C4 14.1217 4.84285 16.1566 6.34315 17.6569C7.84344 19.1571 9.87827 20 12 20C15.73 20 18.84 17.45 19.73 14H17.65C16.83 16.33 14.61 18 12 18C10.4087 18 8.88258 17.3679 7.75736 16.2426C6.63214 15.1174 6 13.5913 6 12C6 10.4087 6.63214 8.88258 7.75736 7.75736C8.88258 6.63214 10.4087 6 12 6C13.66 6 15.14 6.69 16.22 7.78L13 11H20V4L17.65 6.35Z" fill="#636363"/>
+<path d="M17.65 6.35C16.2 4.9 14.21 4 12 4C9.87827 4 7.84344 4.84285 6.34315 6.34315C4.84285 7.84344 4 9.87827 4 12C4 14.1217 4.84285 16.1566 6.34315 17.6569C7.84344 19.1571 9.87827 20 12 20C15.73 20 18.84 17.45 19.73 14H17.65C16.83 16.33 14.61 18 12 18C10.4087 18 8.88258 17.3679 7.75736 16.2426C6.63214 15.1174 6 13.5913 6 12C6 10.4087 6.63214 8.88258 7.75736 7.75736C8.88258 6.63214 10.4087 6 12 6C13.66 6 15.14 6.69 16.22 7.78L13 11H20V4L17.65 6.35Z" fill="#1D9BF0"/>
 </svg>

+ 4 - 0
src/assets/svg/icon-sort-amount.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1 12V10H11.4667V12H1ZM1 5H17V7H1V5ZM1 17V15H8.6V17H1Z" fill="black"/>
+<path d="M16.9798 20V19.1831C18.9112 19.0121 20 18.0115 20 16.403C20 15.0288 19.2127 14.1865 17.638 13.8319L16.9798 13.6989V11.3368C17.638 11.4318 18.1054 11.9257 18.1239 12.5273H19.8339C19.8093 11.0708 18.7021 10.0322 16.9798 9.87392V9H16.1125V9.86759C14.2671 10.0196 13.1845 11.0201 13.1845 12.5717C13.1845 13.8889 13.978 14.7691 15.4605 15.1238L16.1125 15.2821V17.7519C15.3313 17.6632 14.8023 17.1819 14.7592 16.5233H13C13.0062 18.0748 14.181 19.0754 16.1125 19.1894V20H16.9798ZM18.2592 16.6056C18.2592 17.2769 17.7856 17.7075 16.9798 17.7582V15.4404C17.8533 15.6177 18.2592 15.9914 18.2592 16.6056ZM14.9622 12.4134C14.9622 11.8117 15.442 11.3685 16.1125 11.3305V13.5153C15.362 13.3506 14.9622 12.9706 14.9622 12.4134Z" fill="black"/>
+</svg>

+ 4 - 0
src/assets/svg/icon-sort-time.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1 12V10H8.46667V12H1ZM1 5H15V7H1V5ZM1 17V15H6.6V17H1Z" fill="black"/>
+<path d="M17 8C13.14 8 10 11.13 10 15C10 18.87 13.13 22 17 22C20.86 22 24 18.87 24 15C24 11.13 20.87 8 17 8ZM19.19 17.53L16 15.69V12H17.5V14.82L19.94 16.23L19.19 17.53Z" fill="#609FC9"/>
+</svg>

Разлика између датотеке није приказан због своје велике величине
+ 0 - 1
src/assets/svg/icon-three-line.svg


+ 5 - 0
src/assets/svg/icon-user1.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g opacity="0.4">
+<path d="M8 3C8.66304 3 9.29893 3.26339 9.76777 3.73223C10.2366 4.20107 10.5 4.83696 10.5 5.5C10.5 6.16304 10.2366 6.79893 9.76777 7.26777C9.29893 7.73661 8.66304 8 8 8C7.33696 8 6.70107 7.73661 6.23223 7.26777C5.76339 6.79893 5.5 6.16304 5.5 5.5C5.5 4.83696 5.76339 4.20107 6.23223 3.73223C6.70107 3.26339 7.33696 3 8 3ZM8 9.25C10.7625 9.25 13 10.3688 13 11.75V13H3V11.75C3 10.3688 5.2375 9.25 8 9.25Z" fill="white"/>
+</g>
+</svg>

+ 1 - 1
src/assets/svg/icon-while-yes.svg

@@ -1,3 +1,3 @@
 <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 15C11.6421 15 15 11.6421 15 7.5C15 3.35786 11.6421 0 7.5 0C3.35786 0 0 3.35786 0 7.5C0 11.6421 3.35786 15 7.5 15ZM3.96965 8.83499L6.50193 11.3675L7.1218 11.9874L7.6383 11.2791L12.219 4.99666L11.007 4.11293L6.94276 9.68696L5.03035 7.77438L3.96965 8.83499Z" fill="white"/>
+<path d="M3 7.5L7.15975 11.4647L12.8755 3.62562" stroke="white" stroke-width="2"/>
 </svg>

+ 4 - 5
src/entry/background.js

@@ -148,19 +148,18 @@ function thenInstalledMethod() {
     try {
 
         onInstalledCreateTab()
-        onInstalledMid()
         onInstalledUserSet()
         // pingpang
         chrome.alarms.create('PingPong', {
-            //1分鐘之後開始(該值不能小於1) 
+            //1分鐘之後開始(該值不能小於1)
             delayInMinutes: 2,
-            //開始後每一分鐘執行一次(該值不能小于1) 
+            //開始後每一分鐘執行一次(該值不能小于1)
             periodInMinutes: 4
         });
         chrome.alarms.create('LuckMessage', {
-            //1分鐘之後開始(該值不能小於1) 
+            //1分鐘之後開始(該值不能小於1)
             delayInMinutes: 1,
-            //開始後每一分鐘執行一次(該值不能小于1) 
+            //開始後每一分鐘執行一次(該值不能小于1)
             periodInMinutes: 1
         });
     } catch (error) {

+ 19 - 2
src/entry/content.js

@@ -37,7 +37,10 @@ import {
     refreshTabGroup,
     groupTipsSelectGroupTab,
     TwitterApiUserByScreenName,
-    showPublishDialog
+    showPublishDialog,
+    getTweetUserFollowStatus,
+    sendContentByTwitterID,
+    getExtensionStorgeDataForIframe
 } from "@/logic/content/twitter.js";
 
 import { httpBackToContentCallBack } from '@/uilts/chromeExtension.js'
@@ -114,6 +117,14 @@ window.onmessage = (res) => {
             case 'IFRAME_PAGE_JUMP':
                 pageJumpHandler(res.data.data);
                 break;
+            case 'IFRAME_GET_EXTENSION_STORGE_DATA':
+                getExtensionStorgeDataForIframe(res.data.data);
+                break;
+            case 'IFRAME_DO_TASK_CREATE_TWEET':
+                // 做任务
+                // 接受数据,sendmessage
+                console.log('IFRAME_DO_TASK_CREATE_TWEET', res)
+                break
         }
     }
 };
@@ -222,6 +233,12 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
         case 'Hide_ToolBox_By_Nft':
             toolBox.hideBuyNft(req)
             break;
+        case 'IFRAME_API_GET_TWEET_USER_FOLLOW_STATUS':
+            getTweetUserFollowStatus(req);
+            break;
+        case 'GET_CONTENT_BY_TWITTER_ID':
+            sendContentByTwitterID(req.data.tweet_Id)
+            break
     }
     sendResponse && sendResponse('ok');
-})
+})

+ 8 - 2
src/http/fetch.js

@@ -1,9 +1,10 @@
 import { appVersionCode, baseAPIUrl } from '@/http/configAPI.js'
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
+import { guid } from '@/uilts/help'
 
 export async function commonFetch({ url = '', method = 'POST', params = {}, baseInfo = {} }) {
     try {
-
+        let deviceInfo = await getChromeStorage('deviceInfo') || {};
         let storage_mid = await getChromeStorage('mid').catch((error) => {console.log(error) }) || ''
         const { mid } = storage_mid || {}
         if (!baseInfo.token || !baseInfo.uid) {
@@ -17,6 +18,11 @@ export async function commonFetch({ url = '', method = 'POST', params = {}, base
         baseInfo.appType = 1
         baseInfo.loginUid = baseInfo.uid
 
+        baseInfo.fid = deviceInfo.deviceId1;
+        baseInfo.rid = deviceInfo.deviceId2;
+        baseInfo.clientTimestamp = new Date().getTime();
+        baseInfo.requestId = guid();
+
         return new Promise(function (resolve, reject) {
             let _url = baseAPIUrl + url
             if (url.includes('http')) {
@@ -75,4 +81,4 @@ export async function commonFetch({ url = '', method = 'POST', params = {}, base
     } catch (error) {
         console.log('error', error)
     }
-}
+}

+ 16 - 1
src/http/help.js

@@ -1,6 +1,6 @@
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
 import { srcPublishSuccess } from '@/http/publishApi'
-import { bindRepost } from '@/http/treasure'
+import { bindRepost, bindPostContent } from '@/http/treasure'
 
 // 重新绑定推文id
 export const reSetBindTwtterId = ({
@@ -39,3 +39,18 @@ export const reSetBindRepost = (params, callback) => {
     })
 }
 
+
+
+export const reSetBindPostContent = (params, callback) => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (_userInfo && _userInfo.uid) {
+            bindPostContent({
+                params
+            }).then((res) => {
+                if (res.code == 0 || res.code == 3003) {
+                    callback && callback()
+                }
+            })
+        }
+    })
+}

+ 14 - 2
src/http/request.js

@@ -1,9 +1,12 @@
 import axios from 'axios'
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
 import { baseAPIUrl, appVersionCode } from '@/http/configAPI.js'
+import { guid } from '@/uilts/help'
+
 
 let userInfo = '';
 let storage_mid = ''
+let deviceInfo = {};
 
 // 创建axios实例
 export const service = axios.create({
@@ -39,7 +42,11 @@ function checkParams(config) {
         uid,
         appType: 1,
         machineCode: mid,
-        pageSource: pageSource || ''
+        pageSource: pageSource || '',
+        fid: deviceInfo.deviceId1 || '',
+        rid: deviceInfo.deviceId2 || '',
+        clientTimestamp: new Date().getTime(),
+        requestId: guid()
       }
     }
     config['params'] = params;
@@ -64,7 +71,11 @@ function checkParams(config) {
         uid,
         appType: 1,
         machineCode: mid,
-        pageSource: pageSource || ''
+        pageSource: pageSource || '',
+        fid: deviceInfo.deviceId1 || '',
+        rid: deviceInfo.deviceId2 || '',
+        clientTimestamp: new Date().getTime(),
+        requestId: guid()
       }
     }
     config['data'] = data;
@@ -75,6 +86,7 @@ function checkParams(config) {
 // request拦截器
 service.interceptors.request.use(async (config) => {
   userInfo = await getChromeStorage('userInfo') || ''
+  deviceInfo = await getChromeStorage('deviceInfo') || {};
   if (!storage_mid) {
     storage_mid = await getChromeStorage('mid') || ''
   }

+ 17 - 1
src/http/toolBoxApi.js

@@ -18,7 +18,7 @@ export function getAllPostEditorAppData(params) {
 
 export function screenshotWebsite(params) {
     return service({
-        url: `/post/editor/screenshotWebsite`,
+        url: `/post/editor/screenshotWebsiteV2`,
         method: 'post',
         data: params
     })
@@ -47,3 +47,19 @@ export function unlockNftCert(params) {
         data: params
     })
 }
+
+export function getContentTypeConfig(params) {
+  return service({
+      url: `/post/editor/getContentTypeConfig`,
+      method: 'post',
+      data: params
+  })
+}
+
+export function getPostEditorConfig(params) {
+  return service({
+      url: `/post/editor/getConfig`,
+      method: 'post',
+      data: params
+  })
+}

+ 29 - 2
src/http/treasure.js

@@ -27,12 +27,21 @@ export function inviteDetail(params) {
 
 export function inviteList(params) {
     return service({
-        url: `/post/treasure/invite/list`,
+        url: `/post/treasure/invite/list/v2`,
         method: "post",
         data: params,
     });
 }
 
+export function inviteListRefresh(params) {
+    return service({
+        url: `/post/treasure/invite/list/refresh`,
+        method: "post",
+        data: params,
+    });
+
+}
+
 export function treasureOpen(params) {
     return service({
         url: `/post/treasure/open`,
@@ -74,4 +83,22 @@ export function bindRepost(params) {
         method: "post",
         data: params,
     });
-}
+}
+
+export function bindPostContent(params) {
+    return service({
+        url: `/post/bindPostSrcContent`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function receiveListV2(params) {
+    return service({
+        url: `/post/treasure/receive/list/v2`,
+        method: "post",
+        data: params,
+    });
+}
+
+

+ 12 - 7
src/log-center/logEnum.js

@@ -9,6 +9,8 @@ export const redPacketType = {
     nftGroupSale: 3,
     treasure: 4,
     postEditor: 5,
+    giveaway: 0,
+    lottery: 1
 }
 
 export const businessType = {
@@ -26,6 +28,8 @@ export const objectType = {
     loginButton: "login-button",
     withdrawButton: "withdraw-button",
     topupButton: "topup-button",
+    previewNextButton: 'preview-next-button',
+    setPublishContent: 'set-publish-content',
 
 
     getMoreGiveaway: "get-more-giveaway",
@@ -68,7 +72,7 @@ export const objectType = {
     // background文件安装catch异常
     background_function_catch: 'background-function-catch',
     // background 文件chrome 函数 try
-    background_function_try:'background-function-try',
+    background_function_try: 'background-function-try',
     // create Nft
     create_nfts_button: 'create-nfts-button',
     confirm_transfer_button: 'confirm-transfer-button',
@@ -82,6 +86,7 @@ export const objectType = {
     top_right_button: 'top-right-button',
     fullscreen_button: 'fullscreen-button',
     encrypte_nft_button: 'encrypte-nft-button',
+    preRepost: 'preRepost',
 }
 
 export const pageSource = {
@@ -150,11 +155,11 @@ export const bizType = {
 }
 
 export const getCurrentBizType = (type) => {
-  let obj = {};
-  obj[PlayType.common] = bizType.RedPacket;
-  obj[PlayType.lottery] = bizType.Lottery;
-  obj[PlayType.treasure] = bizType.Treasure;
-  obj[PlayType.postEditor] = bizType.ToolBox;
+    let obj = {};
+    obj[PlayType.common] = bizType.RedPacket;
+    obj[PlayType.lottery] = bizType.Lottery;
+    obj[PlayType.treasure] = bizType.Treasure;
+    obj[PlayType.postEditor] = bizType.ToolBox;
 
-  return obj[type];
+    return obj[type];
 }

+ 16 - 14
src/logic/background/facebook.js

@@ -10,21 +10,23 @@ export function facebookShareSuccess(params, sender) {
         let { id } = sender.tab || {};
         chrome.tabs.remove(id);
 
-        fetchAddFinishEvent({
+        if(!data.bizType) {
+          fetchAddFinishEvent({
             eventType: data.type,
             luckdropId: data.taskLuckdropId
-        }).then(res => {
-            if (res.code == 0) {
-                setTimeout(() => {
-                    sendActivetabMessage({
-                        actionType: 'BG_FACEBOOK_SHARE_SUCCESS',
-                        data: data
-                    });
-                })
-            }
-        }).catch((error) => {
-            console.log('catch', error)
-        })
+          }).then(res => {
+              if (res.code == 0) {
+                  setTimeout(() => {
+                      sendActivetabMessage({
+                          actionType: 'BG_FACEBOOK_SHARE_SUCCESS',
+                          data: data
+                      });
+                  })
+              }
+          }).catch((error) => {
+              console.log('catch', error)
+          })
+        }
     } catch (error) {
         Report.reportLog({
             objectType: Report.objectType.background_function_catch,
@@ -52,4 +54,4 @@ function sendActivetabMessage(message = {}) {
             errMsg: error.message
         })
     }
-}
+}

+ 29 - 19
src/logic/background/twitter.js

@@ -222,21 +222,26 @@ export function twitterShortUrl(sender, url) {
 
 
 // 安装插件后获取mid
-export function onInstalledMid() {
+export function onInstalledMid(cb) {
     try {
         getChromeCookie(LANDING_PAGE_MID, (res_arr) => {
             // 没有cookie
             if (res_arr && res_arr.length) {
-                setChromeStorage({ mid: JSON.stringify(res_arr[0]) })
+                setChromeStorage({ mid: JSON.stringify(res_arr[0]) }, () => {
+                  cb && cb()
+                })
             } else {
                 let _params = {
                     mid: guid()
                 }
                 setChromeCookie(LANDING_PAGE, { 'mid': _params.mid })
-                setChromeStorage({ mid: JSON.stringify(_params) })
+                setChromeStorage({ mid: JSON.stringify(_params) }, () => {
+                  cb && cb()
+                })
             }
         })
     } catch (error) {
+        cb && cb();
         Report.reportLog({
             objectType: Report.objectType.background_function_catch,
             funcName: 'onInstalledMid',
@@ -331,17 +336,22 @@ function sendActivetabMessage(message = {}) {
 export function onInstalledCreateTab() {
     try {
         getChromeCookie(LANDING_PAGE_JUMP_INFO, (res = {}) => {
-            setTimeout(() => {
-                if (!res) {
-                    res = {}
-                }
-                // 安装成功埋点
-                Report.reportLog({
-                    objectType: Report.objectType.chrome_extension_installed,
-                    funcName: 'onInstalledCreateTab',
-                    postId: res.postId || ''
-                })
-            }, 5000)
+            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)
+            });
+
             let url = 'https://twitter.com/search?q=%23denet'
             // jump_info
             if (!res || !res.jump_type) {
@@ -442,7 +452,7 @@ export function onInstalledCreateTab() {
 
 /**
  * 在popop重新发送
- * @param {*} req 
+ * @param {*} req
  */
 export function popupRePublish(req) {
     try {
@@ -507,11 +517,11 @@ export async function setMessageCount() {
 function createAlarm() {
     try {
         let alarmInfo = {
-            //1分鐘之後開始(該值不能小於1) 
+            //1分鐘之後開始(該值不能小於1)
             delayInMinutes: 1,
-            //與上方等同的寫法是 
+            //與上方等同的寫法是
             // when : Date.now() + n,
-            //開始後每一分鐘執行一次(該值不能小于1) 
+            //開始後每一分鐘執行一次(該值不能小于1)
             periodInMinutes: 1
         };
 
@@ -730,4 +740,4 @@ const createTabShowGiveaway = (params) => {
     chrome.tabs.create({
         url: params.url,
     });
-}
+}

+ 112 - 38
src/logic/content/ParseCard.js

@@ -1,7 +1,9 @@
+import { iframeHost } from '@/http/configAPI'
 import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
 import ToolBox from '@/view/content/tool-box/index.vue'
 import { createApp } from 'vue'
-
+import { getStorage, setStorage, guid } from '@/uilts/help'
+import { chromeExtensionUrl } from '@/uilts/chromeExtension'
 // 解析卡片类
 // 1.dom匹配
 // 2.找出网页匹配 获取twitterid
@@ -61,19 +63,29 @@ class ParseCard {
         // 是否有#DeNet
         return has_denet
     }
-    parseAllDeNetCard() {
+    parseAllDeNetCard(has_iframe = false) {
         let de_net_card = []
         try {
             let arr_article = document.querySelectorAll('article') || []
             let _txt
             for (let i in arr_article) {
                 _txt = arr_article[i].innerText || ''
-                if ((_txt.includes('#DeNet') || _txt.includes('#DNFT') || this.compatibleMask(arr_article[i])) && !this.isHasIframeByArticle(arr_article[i])) {
-                    de_net_card.push({
-                        time: new Date().getTime(),
-                        dom: arr_article[i]
-                    })
+                if (has_iframe) {
+                    if ((_txt.includes('#DeNet') || _txt.includes('#DNFT') || this.compatibleMask(arr_article[i]))) {
+                        de_net_card.push({
+                            time: new Date().getTime(),
+                            dom: arr_article[i]
+                        })
+                    }
+                } else {
+                    if ((_txt.includes('#DeNet') || _txt.includes('#DNFT') || this.compatibleMask(arr_article[i])) && !this.isHasIframeByArticle(arr_article[i])) {
+                        de_net_card.push({
+                            time: new Date().getTime(),
+                            dom: arr_article[i]
+                        })
+                    }
                 }
+
             }
         } catch (error) {
         }
@@ -154,9 +166,9 @@ class ParseCard {
             return
         }
     }
-    parseAllDeNetCardParmas() {
+    parseAllDeNetCardParmas(has_iframe = false) {
         let json_data = []
-        this.parseAllDeNetCard().forEach((item) => {
+        this.parseAllDeNetCard(has_iframe).forEach((item) => {
             let _obj = this.parseCardParmas(item.dom)
             if (_obj.tweet_Id && _obj.short_url && _obj.dom_card) {
                 _obj.time = item.time
@@ -178,23 +190,24 @@ class ParseCard {
     }
     // 获取短链接和渲染卡片数据
     async getCardParmas(card_json_data) {
-        let sort_link_data = await getChromeStorage('cardData') || []
+        let sort_link_data = getStorage('denetCardData') || []
+        // let sort_link_data = await getChromeStorage('cardData') || []
         let has_post_Id_card_data = this.getLocalHasPostIdData(sort_link_data, card_json_data)
-        let need_net_short_url = this.filterShortUrl(sort_link_data, card_json_data)
+        let need_net_short_urls = this.filterShortUrl(sort_link_data, card_json_data)
 
         // 校验存储大小
         let new_item = this.checkShortUrlArraySize(sort_link_data)
         if (sort_link_data.length != new_item.length) {
-            setChromeStorage({ cardData: JSON.stringify(new_item) })
+            setStorage('denetCardData', new_item)
         }
         return {
             has_post_Id_card_data,
-            need_net_short_url
+            need_net_short_urls
         }
     }
     filterShortUrl(sort_link_data, card_json_data) {
         let has = false
-        let need_net_short_url = []
+        let need_net_short_urls = []
 
         card_json_data.forEach((card_item) => {
             has = false
@@ -204,11 +217,11 @@ class ParseCard {
                 }
             })
             if (!has) {
-                need_net_short_url.push(card_item.short_url)
+                need_net_short_urls.push(card_item.short_url)
             }
         })
         // 返回的是没有postid的
-        return need_net_short_url
+        return need_net_short_urls
     }
     getLocalHasPostIdData(sort_link_data = [], card_json_data = []) {
         // 
@@ -224,8 +237,53 @@ class ParseCard {
         })
         return has_post_Id_card_data
     }
+    netShortUrl(need_net_short_urls = [], callback) {
+        // 1. 获取短链接
+        let denetCardData = getStorage('denetCardData') || []
+
+        need_net_short_urls.forEach((short_url) => {
+            // // 本地没有 存储 
+            if (denetCardData.filter((item) => { return item.short_url == short_url }).length == 0) {
+                denetCardData.push({
+                    short_url
+                })
+            }
+        })
+
+        setStorage('denetCardData', denetCardData)
+
+        // 发起网络请求
+        if (!navigator.onLine) {
+            return
+        }
+        let now_time
+        for (let i in denetCardData) {
+            now_time = new Date().getTime()
+            // 没请求过 || 现在时间 - 网络请求时间 >= 3s && 没有post_Id
+            if ((!denetCardData[i].fetch_time || (now_time - denetCardData[i].fetch_time) >= 3000) && !denetCardData[i].post_Id) {
+                // 发起网络请求请求
+                denetCardData[i].fetch_time = now_time
+                fetch(denetCardData[i].short_url) // 返回一个Promise对象 
+                    .then((res) => {
+                        return res.text() // res.text()是一个Promise对象
+                    }).then((res) => {
+                        res = res.toString()
+                        let str_arr = res.match(/denetme.net\/([\s\S]*?)"/) || []
+                        let post_Id = str_arr[1] || ''
+                        if (!post_Id) {
+                            return
+                        }
+                        denetCardData[i].post_Id = post_Id
+                        setStorage('denetCardData', denetCardData)
+                        callback && callback()
+                    }).catch((error) => {
+                        console.log('catch', error)
+                    })
+            }
+        }
+    }
     checkShortUrlArraySize(_array) {
-        if (new Blob(_array).size >= 1024 * 1024) {
+        if (new Blob(_array).size >= 1024 * 1024 * 4) {
             _array.splice(0, parseInt(_array.length / 2))
         }
         return _array
@@ -238,7 +296,7 @@ class ParseCard {
             tweet_str = `&tweetId=${tweet_Id}`
         }
         _iframe.id = post_Id
-        _iframe_url = chrome.runtime.getURL('/iframe/tool-box.html') + `?page_type=${'card'}&postId=${post_Id}&tweetId=${tweet_Id}`;
+        _iframe_url = chromeExtensionUrl + ('iframe/tool-box.html') + `?page_type=${'card'}&postId=${post_Id}&tweetId=${tweet_Id}`;
         _iframe.allow = "camera *;microphone *"
         // debugger mode
         if (window.location.href.includes('denet_debugger')) {
@@ -257,7 +315,7 @@ class ParseCard {
             tweet_str = `&tweetId=${tweet_Id}`
         }
         _iframe.id = post_Id
-        _iframe_url = chrome.runtime.getURL('/iframe/red-packet.html') + `?postId=${post_Id}${tweet_str}&tweet_author=${tweet_author}&window_origin=${window.location.origin}&page_type=${page_type}`;
+        _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}`;
         // debugger mode
         if (window.location.href.includes('denet_debugger')) {
             _iframe_url = _iframe_url + '&denet_debugger=1'
@@ -274,22 +332,22 @@ class ParseCard {
         let projectId = project_arr[0]
         let _iframe = document.createElement('iframe')
         _iframe.id = project_Id
-        _iframe.src = chrome.runtime.getURL('/iframe/nft-card.html') + `?projectId=${projectId}&tweetId=${tweet_Id}&twitterAccount=${project_arr[1]}`;
+        _iframe.src = chromeExtensionUrl + ('iframe/nft-card.html') + `?projectId=${projectId}&tweetId=${tweet_Id}&twitterAccount=${project_arr[1]}`;
         _iframe.style.cssText = 'border:medium none; width:375px; min-height:300px;'
         return _iframe
     }
     createNftGroupIframe({ project_Id, tweet_Id }) {
         let _iframe = document.createElement('iframe')
         _iframe.id = project_Id
-        _iframe.src = chrome.runtime.getURL('/iframe/nft-group-card.html') + `?projectId=${project_Id}&tweet_Id=${tweet_Id}`;
+        _iframe.src = chromeExtensionUrl + ('iframe/nft-group-card.html') + `?projectId=${project_Id}&tweet_Id=${tweet_Id}`;
         _iframe.style.cssText = 'border:medium none; width:505px; min-height:180px;'
         return _iframe
     }
-    createTreasureIframe(params = { page_type, tweet_Id, post_Id, invite_code }) {
+    createTreasureIframe(params = { page_type, tweet_Id, post_Id, invite_code, invite_channel }) {
         let _iframe = document.createElement('iframe')
         _iframe.id = params.post_Id
-        _iframe.src = chrome.runtime.getURL('/iframe/treasure-hunt.html') + `?params=${JSON.stringify(params)}`;
-        _iframe.style.cssText = 'border:medium none; width:375px; min-height:500px; border: 1px solid #DCDCDC; border-radius: 20px;'
+        _iframe.src = chromeExtensionUrl + ('iframe/treasure-hunt.html') + `?params=${JSON.stringify(params)}&iframeId=${guid()}`;
+        _iframe.style.cssText = 'border:medium none; width:375px; min-height:580px; border: 1px solid #DCDCDC; border-radius: 20px;'
         return _iframe
     }
     isHasIframeByArticle(dom_card) {
@@ -480,7 +538,7 @@ class ParseCard {
             dom.appendChild(this.createIframe({ post_Id, tweet_Id, page_type }))
         }
     }
-    replaceDOMTreasureCard({ invite_code, dom_card, tweet_Id, post_Id, time, short_url, page_type = '' }) {
+    replaceDOMTreasureCard({ invite_code, dom_card, tweet_Id, post_Id, time, short_url, page_type = '', invite_channel }) {
         if (!dom_card || !dom_card.parentElement) {
             return
         }
@@ -500,7 +558,7 @@ class ParseCard {
 
         dom.style = 'min-height:500px'
         if (dom) {
-            dom.appendChild(this.createTreasureIframe({ post_Id, tweet_Id, page_type, invite_code }))
+            dom.appendChild(this.createTreasureIframe({ post_Id, tweet_Id, page_type, invite_code, invite_channel }))
         }
     }
     replaceNftDomRedPacket({ dom_card, tweet_Id, post_Id, time, short_url }) {
@@ -528,28 +586,34 @@ class ParseCard {
         if (!dom_card || !dom_card.parentElement) {
             return
         }
-        let dom = dom_card.querySelector('div[id^=jsc_c_]').parentElement
-        dom.style = 'min-height:500px'
+        let card = dom_card.querySelector('div[id^=jsc_c_]');
+        let dom = card && card.parentElement;
         if (dom) {
-            for (let i = 0; i < dom.childNodes.length; i++) {
-                if (dom.childNodes[i].dataset && dom.childNodes[i].dataset.testid && dom.childNodes[i].dataset.testid == 'card.wrapper') {
-                    dom.children[i].style.display = 'none'
-                }
-            }
-
-            if (dom.nextElementSibling && dom.nextElementSibling.id && dom.nextElementSibling.id.indexOf('jsc_c_') >= 0) {
-                dom.nextElementSibling.style.display = 'none'
-            }
             let originUrl = new URL(short_url);
             let post_Id = originUrl.pathname.slice(1);
 
             if (post_Id.indexOf('luckdraw/') >= 0) {
+                hideImage(dom);
+                dom.style = 'min-height:500px'
                 post_Id = post_Id.replace('luckdraw/', '');
                 dom.appendChild(this.createIframe({ post_Id, tweet_author, page_type: '抽奖' }, true))
-            } else if (!post_Id.includes('/')) {
+            } else if (post_Id.indexOf('/') === -1) {
+                hideImage(dom);
+                dom.style = 'min-height:500px'
                 dom.appendChild(this.createIframe({ post_Id, tweet_author }, true))
             }
         }
+
+        function hideImage(dom) {
+            for (let i = 0; i < dom.childNodes.length; i++) {
+                if (dom.childNodes[i].dataset && dom.childNodes[i].dataset.testid && dom.childNodes[i].dataset.testid == 'card.wrapper') {
+                    dom.children[i].style.display = 'none'
+                }
+            }
+            if (dom.nextElementSibling && dom.nextElementSibling.id && dom.nextElementSibling.id.indexOf('jsc_c_') >= 0) {
+                dom.nextElementSibling.style.display = 'none'
+            }
+        }
     }
     replaceNftGroupDomRedPacket({ dom_card, tweet_Id, post_Id, time, short_url }) {
         if (!dom_card || !dom_card.parentElement) {
@@ -572,5 +636,15 @@ class ParseCard {
             dom.appendChild(this.createNftGroupIframe({ project_Id, tweet_Id }))
         }
     }
+    // 根据推特id获取文章推文
+    getContentByTwitterId(tweet_Id) {
+        let txt = ''
+        let card_json_data = this.parseAllDeNetCardParmas(true)
+        let result = card_json_data.filter((item) => { return item.tweet_Id == tweet_Id }) || []
+        if (result.length > 0 && result[0].dom_card) {
+            txt = result[0].dom_card.querySelector('[data-testid="tweetText"]').innerText.replace('…', ' ')
+        }
+        return txt
+    }
 }
 export default new ParseCard()

+ 6 - 4
src/logic/content/ToolBox.js

@@ -1,4 +1,6 @@
 import { $ } from "@/uilts/help";
+import { chromeExtensionUrl } from '@/uilts/chromeExtension'
+
 export let toolbox_fixed_tweetId = ''
 
 export const toolBox = new class ToolBox {
@@ -18,7 +20,7 @@ export const toolBox = new class ToolBox {
             display:none;
             border:medium none;  filter: drop-shadow(rgba(0, 0, 0, 0.2) 0px 4px 20px);
             `
-        iframe.src = chrome.runtime.getURL('/iframe/tool-box.html') + `?page_type=${'full'}`;
+        iframe.src = chromeExtensionUrl + ('iframe/tool-box.html') + `?page_type=${'full'}`;
         iframe.allow = "camera *;microphone *"
         document.body.append(iframe)
     }
@@ -59,12 +61,12 @@ export const toolBox = new class ToolBox {
     // 购买NFT
     buyNft(req) {
         let iframe = document.createElement('iframe')
-            iframe.src = chrome.runtime.getURL('/iframe/tool-box-buy-nft.html') + `?postId=${req.data.postId}`;
+        iframe.src = chromeExtensionUrl + ('iframe/tool-box-buy-nft.html') + `?postId=${req.data.postId}`;
         let ifAppend = document.querySelector('#denet-tool-box-buy-nft')
         if (ifAppend) return;
         let div = document.createElement(`div`);
-            div.id = 'denet-tool-box-buy-nft';
-            div.innerHTML = `
+        div.id = 'denet-tool-box-buy-nft';
+        div.innerHTML = `
                 ${iframe.outerHTML}
                 <div class="mask_bg"></div>
                 <style>

+ 2 - 2
src/logic/content/facebook.js

@@ -17,7 +17,7 @@ export function initFacebookContent() {
 
 /**
  * 注入分享页面逻辑
- * @returns 
+ * @returns
  */
 function injectShareCode() {
     const {href, pathname} = window.location;
@@ -66,4 +66,4 @@ function shareCallback() {
             chrome.runtime.sendMessage({ actionType: "CONTENT_FACEBOOK_SHARE_SUCCESS", data: params })
         }
     }
-}
+}

+ 41 - 2
src/logic/content/help/twitter.js

@@ -1,3 +1,5 @@
+import { getStorage, setStorage, getVisitorId, setCookie, getCookie, guid } from '@/uilts/help'
+import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
 
 // 根据提示dom 跳转到推文详情页面
 export const jumpTwitterDetailByAlert = () => {
@@ -38,6 +40,43 @@ export const showEditTweet = (callback) => {
             clearInterval(timer)
             callback && callback()
         }
-        num-- 
+        num--
     }, 500);
-}
+}
+
+export const setDeviceInfo = async () => {
+  const deviceStorageParams = {
+    name: 'de_net_device_id_1'
+  }
+
+  const deviceCookieParams = {
+    url: 'https://twitter.com/',
+    name: 'de_net_device_id_2'
+  }
+
+  let deviceInfo = {
+    deviceId1: '',
+    deviceId2: ''
+  }
+
+  let storageDeviceInfo = getStorage(deviceStorageParams.name);
+  if(!storageDeviceInfo) {
+    let res = await getVisitorId();
+    let id =  res && res.visitorId || '';
+    setStorage(deviceStorageParams.name, id);
+    deviceInfo.deviceId1 = id;
+  } else {
+    deviceInfo.deviceId1 = storageDeviceInfo;
+  }
+
+  let cookieDeviceInfo = getCookie(deviceCookieParams.name);
+  if(!cookieDeviceInfo) {
+    let rid = guid();
+    setCookie(deviceCookieParams.name, rid, 600);
+    deviceInfo.deviceId2 = rid;
+  } else {
+    deviceInfo.deviceId2 = cookieDeviceInfo;
+  }
+
+  setChromeStorage({'deviceInfo': JSON.stringify(deviceInfo)});
+}

+ 38 - 38
src/logic/content/nft.js

@@ -1,6 +1,6 @@
 import { getOffsetRect, nextTick } from '@/uilts/help'
 import { listJoinNftGroup } from '@/http/nft';
-import { getChromeStorage } from '@/uilts/chromeExtension.js'
+import { getChromeStorage, chromeExtensionUrl } from '@/uilts/chromeExtension.js'
 import { _setPublishContent, publishNFTTweetPost, bindTwitterArt, bindTwitterArtMethod } from './twitter';
 import { jumpTwitterDetailByAlert } from '@/logic/content/help/twitter.js'
 import Report from "@/log-center/log"
@@ -18,29 +18,29 @@ export const showNFTGroupIcon = () => {
     let where = isTwitter && toolElem && !isAppend && ifShowNftGroup;
     if (where) {
         let oDiv = document.createElement(`div`);
-            oDiv.id = 'de-nft-group-enter';
+        oDiv.id = 'de-nft-group-enter';
         let oImg = document.createElement('img');
-            oImg.src = groupImgNoSelect;
-            oImg.className = 'addGroup';
-            oDiv.innerHTML = `
+        oImg.src = groupImgNoSelect;
+        oImg.className = 'addGroup';
+        oDiv.innerHTML = `
                 ${oImg.outerHTML}
                 <style>
                     #de-nft-group-enter {position:relative; display:flex; padding:0 8px;}
                     #de-nft-group-enter .addGroup {cursor:pointer; height:32px;}
                 </style>
             `;
-            oDiv.addEventListener('click', (e) => {
-                showNFTGroupList(e);
-                e.stopPropagation();
-                // report
-                Report.reportLog({
-                    pageSource: Report.pageSource.mainPage,
-                    businessType: Report.businessType.buttonClick,
-                    objectType: Report.objectType.buttonSecond
-                }, {
-                    type: 2
-                });
-            })
+        oDiv.addEventListener('click', (e) => {
+            showNFTGroupList(e);
+            e.stopPropagation();
+            // report
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonClick,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 2
+            });
+        })
         toolElem.firstChild.appendChild(oDiv)
         // report
         Report.reportLog({
@@ -61,11 +61,11 @@ export const showNFTGroupList = (e) => {
     let wHeight = document.body.offsetHeight || document.body.clientHeight;
     if ((top + height + 290) > wHeight) oTop = top - 290;
     let iframe = document.createElement('iframe');
-        iframe.src = chrome.runtime.getURL(`/iframe/nft-group.html`)
-        iframe.style.cssText = 'border:medium none; width:315px; height:260px;';
+    iframe.src = chromeExtensionUrl + (`iframe/nft-group.html`)
+    iframe.style.cssText = 'border:medium none; width:315px; height:260px;';
     let html = document.createElement('div');
-        html.id = 'de-nft-group-list';
-        html.innerHTML = `
+    html.id = 'de-nft-group-list';
+    html.innerHTML = `
             <div class="de-nft-group-div">
                 ${iframe.outerHTML}
             </div>
@@ -141,11 +141,11 @@ export const endPostContent = () => {
     return new Promise((resolve) => {
         let inputEle = document.querySelector('div[contenteditable="true"]');
         let range = document.createRange();
-            range.selectNodeContents(inputEle);
-            range.collapse(false);
+        range.selectNodeContents(inputEle);
+        range.collapse(false);
         let sel = window.getSelection();
-            sel.removeAllRanges();
-            sel.addRange(range);
+        sel.removeAllRanges();
+        sel.addRange(range);
         resolve()
     })
 }
@@ -171,7 +171,7 @@ export const setNFTGroupContent = (res) => {
         nextTick(() => {
             _addTweetButtonListen()
         }, 100)
-        
+
     } else {
         endPostContent().then(() => {
             let inputEle = document.querySelector('div[contenteditable="true"]');
@@ -195,38 +195,38 @@ export const elemAddEventListener = (elem, action, fn) => {
 
 
 export const addJoinedGroupList = () => {
-    if(ifShowNftGroup) {
-        let {pathname} = window.location;
+    if (ifShowNftGroup) {
+        let { pathname } = window.location;
 
         let iframe = document.createElement('iframe');
-            iframe.id = 'de-joined-group-list';
-            iframe.src = chrome.runtime.getURL('/iframe/joined-group-list.html');
-            iframe.style.cssText = `border: medium none;height: 120px;border-radius: 16px;margin-bottom: 16px`
+        iframe.id = 'de-joined-group-list';
+        iframe.src = chromeExtensionUrl + ('iframe/joined-group-list.html');
+        iframe.style.cssText = `border: medium none;height: 120px;border-radius: 16px;margin-bottom: 16px`
 
         let iframeContent = document.getElementById('de-joined-group-list');
 
         if (!iframeContent && pathname == '/home') {
             let sidebarColumn = document.querySelector('div[data-testid="sidebarColumn"]');
-            if(sidebarColumn) {
+            if (sidebarColumn) {
                 let searchDom = sidebarColumn.querySelector('form[role="search"]');
-                if(searchDom) {
+                if (searchDom) {
                     let listWrapperDom = searchDom.parentElement.parentElement.parentElement.parentElement;
-                    if(listWrapperDom) {
+                    if (listWrapperDom) {
                         let listParent = listWrapperDom.parentElement;
-                        if(listParent) {
+                        if (listParent) {
                             listParent.insertBefore(iframe, listWrapperDom.nextElementSibling.nextElementSibling);
                         }
                     }
                 }
-            } 
+            }
         }
     }
 };
 
 export const setJoinedGroupIframeStyle = (params) => {
-    let {height = '321px'} = params;
+    let { height = '321px' } = params;
     let iframeContent = document.getElementById('de-joined-group-list');
-    if(iframeContent) {
+    if (iframeContent) {
         iframeContent.style.height = height;
     }
 }

+ 229 - 93
src/logic/content/twitter.js

@@ -1,7 +1,8 @@
-import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
-import { throttle, getQueryString, getCookie, nextTick, getQueryStringByUrl } from '@/uilts/help'
+import { getChromeStorage, setChromeStorage, chromeExtensionUrl } from '@/uilts/chromeExtension.js'
+import { throttle, getQueryString, getCookie, nextTick, getQueryStringByUrl, getStorage, setStorage, getInnerIframeURL } from '@/uilts/help'
 import { discordAuthRedirectUri, iframeHost } from '@/http/configAPI'
 import { reportSrcPublishEvent } from '@/http/publishApi'
+
 import Report from "@/log-center/log"
 import { fetchAddFinishEvent } from '@/logic/background/fetch/facebook';
 import { showNFTGroupIcon, hideNFTGroupList, checkUserJoinGroup, elemAddEventListener, addJoinedGroupList } from '@/logic/content/nft';
@@ -11,6 +12,9 @@ import { keywordReminderInit } from '@/logic/content/keywordReminder.js'
 import { toolBox } from '@/logic/content/ToolBox'
 import axios from 'axios';
 import messageCenter from '@/uilts/messageCenter';
+import { PlayType } from '@/types';
+import { reSetBindPostContent } from '@/http/help.js';
+import { setDeviceInfo } from '@/logic/content/help/twitter';
 
 let dom = {};
 
@@ -24,6 +28,7 @@ let systemInfo = {
     theme: 'light'
 }
 
+
 let fixProfileTabAutoTimer = null;
 
 
@@ -117,6 +122,13 @@ export function showTwitterPublishDialogHandler(publishRes) {
     // _setPublishContent(publishRes.srcContent);
     setDialogPublishContent(publishRes.srcContent);
     _publishTweetEvent(publishRes, bindTwitterArtMethod);
+
+    Report.reportLog({
+        businessType: Report.businessType.pageView,
+        objectType: Report.objectType.setPublishContent,
+        postId: publishRes.postId
+    }, {
+    });
 }
 
 export function twitterPublishHandler(res) {
@@ -226,12 +238,30 @@ function _publishTweetEvent(params, cb) {
             bindTwitterArt.needBind = true;
             bindTwitterArt.postId = params.postId;
             tweetPublishStore.showPublishDialog = false;
+
+            bindContentStr(params);
             // checkIsShowReSend(dialog, params);
             cb && cb()
         });
     }, 800)
 }
 
+function bindContentStr(params) {
+    if (params && params.postBizData) {
+        if (typeof params.postBizData == 'string') {
+            let objBizData = JSON.parse(params.postBizData);
+            let inputEle = document.querySelector('div[contenteditable="true"]');
+            if (objBizData.luckdropType == PlayType.treasure && inputEle) {
+                let textContent = inputEle.innerText;
+                reSetBindPostContent({
+                    postId: params.postId,
+                    postSrcContent: textContent,
+                })
+            }
+        }
+    }
+}
+
 function onClosePublishDialogHandle(dom, params) {
     // 如果是 Tool box
     if (params.postType == 3) {
@@ -401,7 +431,7 @@ function _addIframe() {
     // let span = document.createElement('span');
     // const shadowRoot = span.attachShadow({mode: 'closed'})
     let iframe = document.createElement('iframe');
-    iframe.src = chrome.runtime.getURL('/iframe/publish.html')
+    iframe.src = chromeExtensionUrl + ('iframe/publish.html')
     iframe.id = 'iframe-content'
     iframe.style.cssText = 'position:fixed;top:0px;right:0;display:block; width:100%;height:100%;z-index:10000; border: medium none;display:none;background: rgba(255,255,255,0);';
     // shadowRoot.appendChild(iframe);
@@ -424,9 +454,9 @@ function addPublishTipsIframe(params = {}) {
             let iframe = document.createElement('iframe');
             iframe.id = 'de-publish-tips'
             if (params.type == 'nft') {
-                iframe.src = chrome.runtime.getURL('/iframe/publish-tips.html?type="nft"');
+                iframe.src = chromeExtensionUrl + ('iframe/publish-tips.html?type="nft"');
             } else {
-                iframe.src = chrome.runtime.getURL('/iframe/publish-tips.html');
+                iframe.src = chromeExtensionUrl + ('iframe/publish-tips.html');
             }
 
             iframe.style.cssText = `border: medium none; width:270px;height:500px;position: fixed; right: ${right}px; top: 5%;z-index: -1`
@@ -443,7 +473,7 @@ export function noticeBindTweet(params) {
     hidePopupPage();
     let iframe = document.createElement('iframe');
     iframe.id = 'de-notice-bind-tweet';
-    iframe.src = chrome.runtime.getURL('/iframe/bind-tweet.html') + `?params=${JSON.stringify(params)}`;
+    iframe.src = chromeExtensionUrl + ('iframe/bind-tweet.html') + `?params=${JSON.stringify(params)}`;
     iframe.style.cssText = `border: medium none; width:400px;min-height:313px;position: fixed; right: 16px; top: 16px;border-radius: 20px;`
     let iframeContent = document.getElementById('de-notice-bind-tweet');
     if (!iframeContent) {
@@ -532,7 +562,7 @@ const setDialogPublishContent = throttle(function (content) {
         if (inputEle) {
             inputEle.dispatchEvent(event);
         }
-    }, 300)
+    }, 800)
 }, 600);
 
 /**
@@ -835,73 +865,80 @@ function onChangePageMain(targetNode) {
 // 2.监听卡片是否可见
 // 3.如果可见了 去找
 
-function setIframeRedPacket(type = 'twitter') {
+function setIframeCard(type = 'twitter') {
     // 获取所有卡片参数
     let card_json_data
-    switch (type) {
-        case 'facebook':
-            card_json_data = parseCard.parseFacebookCardParmas()
-            for (let i in card_json_data) {
-                parseCard.replaceFacebookPacket(card_json_data[i])
-            }
-            break;
-        default:
-            card_json_data = parseCard.parseAllDeNetCardParmas()
-            // 过滤出可以请求的短链接
-            parseCard.getCardParmas(card_json_data).then((res) => {
-                for (let i in res.has_post_Id_card_data) {
-                    let item = res.has_post_Id_card_data[i];
-                    if (item && item.post_Id && item.post_Id.indexOf('nft/') >= 0) {
-                        parseCard.replaceNftDomRedPacket(item)
-                    } else if (item && item.post_Id && item.post_Id.indexOf('nft_group/') >= 0) {
-                        parseCard.replaceNftGroupDomRedPacket(item)
-                    } else if (item && item.post_Id && item.post_Id.indexOf('luckdraw/') >= 0) {
-                        item.post_Id = item.post_Id.split('luckdraw/')[1] || ''
-                        item.page_type = '抽奖'
-                        parseCard.replaceDOMRedPacket(item)
-                    } else if (item && item.post_Id && item.post_Id.indexOf('toolbox/') >= 0) {
-                        item.page_type = 'toolbox'
-                        item.post_Id = item.post_Id.split('toolbox/')[1] || ''
-                        if (item.post_Id) {
-                            parseCard.replaceIframeToolBox(item)
-                        }
-                    } else if (item && item.post_Id && !item.post_Id.includes('/')) {
-                        item.page_type = '红包'
-                        parseCard.replaceDOMRedPacket(item)
-                        // 夺宝链接
-                    } else if (item && item.post_Id && item.post_Id.includes('treasure/')) {
-                        // https://testh5.denetme.net/treasure/{postid}
-                        // https://testh5.denetme.net/treasure/invite/{inviteCode}
-                        // 邀请链接
-                        if (item.post_Id.includes('invite/')) {
-                            item.invite_code = item.post_Id.split('invite/')[1] || ''
-                            item.page_type = '邀请链接'
-                            if (item.invite_code) {
-                                item.post_Id = ''
-                                parseCard.replaceDOMTreasureCard(item)
-                            }
-                        } else {
-                            // 原始链接
-                            item.page_type = '原始链接'
-                            item.post_Id = item.post_Id.split('treasure/')[1] || ''
-                            if (item.post_Id) {
-                                parseCard.replaceDOMTreasureCard(item)
+    if (type == 'facebook') {
+        card_json_data = parseCard.parseFacebookCardParmas()
+        for (let i in card_json_data) {
+            parseCard.replaceFacebookPacket(card_json_data[i])
+        }
+    }
+    else if (type == 'twitter') {
+        card_json_data = parseCard.parseAllDeNetCardParmas()
+        // 过滤出可以请求的短链接
+        parseCard.getCardParmas(card_json_data).then((res) => {
+            for (let i in res.has_post_Id_card_data) {
+                let item = res.has_post_Id_card_data[i];
+                if (item && item.post_Id && item.post_Id.indexOf('nft/') >= 0) {
+                    parseCard.replaceNftDomRedPacket(item)
+                } else if (item && item.post_Id && item.post_Id.indexOf('nft_group/') >= 0) {
+                    parseCard.replaceNftGroupDomRedPacket(item)
+                } else if (item && item.post_Id && item.post_Id.indexOf('luckdraw/') >= 0) {
+                    item.post_Id = item.post_Id.split('luckdraw/')[1] || ''
+                    item.page_type = '抽奖'
+                    parseCard.replaceDOMRedPacket(item)
+                } else if (item && item.post_Id && item.post_Id.indexOf('toolbox/') >= 0) {
+                    item.page_type = 'toolbox'
+                    item.post_Id = item.post_Id.split('toolbox/')[1] || ''
+                    if (item.post_Id) {
+                        parseCard.replaceIframeToolBox(item)
+                    }
+                } else if (item && item.post_Id && !item.post_Id.includes('/')) {
+                    item.page_type = '红包'
+                    parseCard.replaceDOMRedPacket(item)
+                    // 夺宝链接
+                } else if (item && item.post_Id && item.post_Id.includes('treasure/')) {
+                    // https://testh5.denetme.net/treasure/{postid}
+                    // https://testh5.denetme.net/treasure/invite/{inviteCode}
+                    // 邀请链接
+                    if (item.post_Id.includes('invite/')) {
+                        let arr = item.post_Id.split('/')
+                        let index
+                        for (let i in arr) {
+                            index = Number(i) + 1
+                            if (arr[i] == 'invite' && arr.length >= index) {
+                                item.invite_code = arr[index];
+                                if(arr.length > index + 1) {
+                                  item.invite_channel = arr[index+1];
+                                } else {
+                                  item.invite_channel = '';
+                                }
+                                break
                             }
                         }
-                    }
-                }
-                if (res.need_net_short_url.length > 0) {
-                    // 请求短链接
-                    chrome.runtime.sendMessage({ actionType: "CONTENT_TWITTER_SHORT_LINK", data: "", arr_url: res.need_net_short_url }, (res) => {
-                        if (!res) {
-                            Report.reportLog({
-                                objectType: Report.objectType.parse_card_error
-                            });
+
+                        item.page_type = '邀请链接'
+                        if (item.invite_code) {
+                            item.post_Id = ''
+                            parseCard.replaceDOMTreasureCard(item)
                         }
-                    })
+                    } else {
+                        // 原始链接
+                        item.page_type = '原始链接'
+                        item.post_Id = item.post_Id.split('treasure/')[1] || ''
+                        if (item.post_Id) {
+                            parseCard.replaceDOMTreasureCard(item)
+                        }
+                    }
                 }
-            })
-            break;
+            }
+            if (res.need_net_short_urls.length > 0) {
+                parseCard.netShortUrl(res.need_net_short_urls, () => {
+                    changeQueueNum(5)
+                })
+            }
+        })
     }
 }
 
@@ -928,7 +965,7 @@ export function initExecuteScript(changes) {
             init()
         }
     }
-    if (changes.userInfo) {
+    if (changes.userInfo && changes.userInfo.newValue) {
         let item = JSON.parse(changes.userInfo.newValue)
         if (item) {
             checkUserJoinGroup(() => {
@@ -967,7 +1004,7 @@ function initParseCard() {
                     return
                 }
                 initGroupTip()
-                setIframeRedPacket()
+                setIframeCard()
                 checkHasSliderDeBtn();
                 changeQueueNum(-1)
                 showNFTCard()
@@ -981,7 +1018,7 @@ function initParseCard() {
                 if (queue_num <= 0) {
                     return
                 }
-                setIframeRedPacket('facebook')
+                setIframeCard('facebook')
                 changeQueueNum(-1)
             }, 1000)
         }
@@ -1026,6 +1063,7 @@ export function init() {
         addJoinedGroupList();
         getSysTheme();
         addGroupTab();
+        setDeviceInfo();
         // 预加载全屏 toobbox
         toolBox.initFull()
     }
@@ -1058,6 +1096,31 @@ export function init() {
     });
 }
 
+export const getTweetUserFollowStatus = (params) => {
+    let { tweetId, userList } = params.data;
+    let promiseList = [];
+    for (let i = 0; i < userList.length; i++) {
+        promiseList[i] = TwitterApiUserByScreenNameReq({ screen_name: userList[i]['name'] });
+    }
+
+    Promise.allSettled(promiseList).then((res) => {
+        let list = [];
+        if (res && res.length) {
+          let resList = res.filter(item => item.status == 'fulfilled');
+          for (let i = 0; i < resList.length; i++) {
+              let item = resList[i];
+              if (item && item.value && item.value.data && item.value.data.data) {
+                  list.push(item.value.data.data)
+              }
+          }
+        }
+
+        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 }, () => { })
+    })
+}
+
 function onPageVisbile() {
     document.addEventListener('visibilitychange', function () {
         let isHidden = document.hidden;
@@ -1315,10 +1378,12 @@ export function checkTwitterTaskState() {
         })
         // 点击取消
         clickByDataTestId(e, 'confirmationSheetCancel', () => {
+            console.log('DO_TASK1')
             chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: false }, () => { })
         })
         // 点击 蒙层
         if (e.target && e.target.nextSibling && e.target.nextSibling.dataset && e.target.nextSibling.dataset.testid == 'confirmationSheetDialog') {
+            console.log('DO_TASK2')
             chrome.runtime.sendMessage({ actionType: "DO_TASK", tweet_Id, task_type, task_data, task_done: false }, () => { })
         }
     }, true)
@@ -1373,7 +1438,7 @@ export function getTweetAuthorByDom(params) {
         }
     }
 }
-export function doTaskTwitterAPI({ task_data, task_type, tasks }) {
+export function doTaskTwitterAPI({ task_data, task_type, tasks, iframeId }) {
     switch (task_type) {
         case 'like':
             TwitterLikeAPI(task_data.tweet_Id)
@@ -1396,7 +1461,7 @@ export function doTaskTwitterAPI({ task_data, task_type, tasks }) {
                     case '1':
                         item.relatedUsers.forEach((item) => {
                             if (item.name && item.twitterUserId) {
-                                TwitterFollowAPI(item, task_data.tweet_Id)
+                                TwitterFollowAPI(item, task_data.tweet_Id);
                             }
                         })
                         break
@@ -1408,7 +1473,7 @@ export function doTaskTwitterAPI({ task_data, task_type, tasks }) {
                     // 推文发推
                     case '10':
                         // 发推
-                        TwitterApiCreateTweet({ text: task_data.tweet_text, tweet_Id: task_data.tweet_Id })
+                        TwitterApiCreateTweet({ text: task_data.tweet_text, tweet_Id: task_data.tweet_Id, iframeId })
                         break
                 }
 
@@ -1421,7 +1486,49 @@ export function showJoinDialog(data) {
     let iframe = document.querySelector('#nftProjectId')
     iframe.style.display = 'block'
     iframe.contentWindow.postMessage({ actionType: 'SHOW_JOIN_DATA', data }, '*');
-    iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/group?params=${JSON.stringify(data)}&time=${new Date().getTime()}`)
+    iframe.src = chromeExtensionUrl + (`iframe/buy-nft.html#/group?params=${JSON.stringify(data)}&time=${new Date().getTime()}`)
+}
+
+const TwitterFriendshipsUpdate = (params) => {
+  let {id = '', device = true, name} = params || {};
+  let data = {
+    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,
+    cursor: -1,
+    id,
+    device
+  }
+  if(!id) {
+    return;
+  }
+  return fetch("https://twitter.com/i/api/1.1/friendships/update.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": "en",
+          "referer": `https://twitter.com/${name}`
+      },
+      "referrer": `https://twitter.com/${name}`,
+      "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&cursor=-1&id=${id}&device=true`,
+      "method": "POST",
+      "mode": "cors",
+      "credentials": "include"
+  })
 }
 
 const TwitterFollowAPI = (item, tweet_Id) => {
@@ -1447,8 +1554,11 @@ const TwitterFollowAPI = (item, tweet_Id) => {
         let task_data = {
             follow_name: item.name
         }
+        TwitterFriendshipsUpdate({id: item.twitterUserId, name: item.name})
+
         chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'follow', task_data, task_done: true }, () => { })
     }).catch(() => {
+        console.log('DO_TASK3')
         chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'follow', task_data, task_done: false }, () => { })
     })
 }
@@ -1481,6 +1591,7 @@ const TwitterRetweetAPI = (tweet_Id) => {
     }).then(() => {
         chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'retweet', task_data: '', task_done: true }, () => { })
     }).catch(() => {
+        console.log('DO0_TASK4')
         chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'retweet', task_data: '', task_done: false }, () => { })
     })
 }
@@ -1512,12 +1623,12 @@ const TwitterLikeAPI = (tweet_Id) => {
     }).then(() => {
         chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'like', task_data: '', task_done: true }, () => { })
     }).catch(() => {
+        console.log('DO_TASK5')
         chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'like', task_data: '', task_done: false }, () => { })
     })
 }
 
-
-const TwitterApiCreateTweet = ({ text, tweet_Id }) => {
+const TwitterApiCreateTweet = ({ text, tweet_Id, iframeId }) => {
     let data = {
         queryId: "hC1nuE-2d1NX5LYBuuAvtQ",
         features: {
@@ -1563,16 +1674,15 @@ const TwitterApiCreateTweet = ({ text, tweet_Id }) => {
             "x-twitter-client-language": "en"
         },
     }).then(function (response) {
-        chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet', task_data: '', task_done: true, response })
+        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: 'createTweet', task_data: '', task_done: false })
+        chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet1', task_data: '', task_done: '否', iframeId })
     });
 }
 
-
-export const TwitterApiUserByScreenName = (params) => {
-    let { screen_name, tweetId = '', objectType = '' } = params;
-    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`, {
+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`, {
         headers: {
             "accept": "*/*",
             "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
@@ -1589,10 +1699,17 @@ export const TwitterApiUserByScreenName = (params) => {
             "x-twitter-auth-type": "OAuth2Session",
             "x-twitter-client-language": "en"
         },
-    }).then(function (response) {
-        chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: response.data.data || {}, tweetId, objectType }, () => { })
+    })
+}
+
+
+export const TwitterApiUserByScreenName = (params, cb) => {
+    let { screen_name, tweetId = '', objectType = '', iframeId = '' } = params;
+
+    TwitterApiUserByScreenNameReq({ screen_name }).then(function (response) {
+        chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: response.data.data || {}, tweetId, objectType, iframeId }, () => { })
     }).catch(function (err) {
-      chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: {}, tweetId, objectType }, () => { })
+        chrome.runtime.sendMessage({ actionType: "CONTENT_API_GET_TWEET_USER_INFO_RES", data: {}, tweetId, objectType, iframeId }, () => { })
     });
 }
 
@@ -1749,7 +1866,7 @@ const initGroupTip = () => {
         if (iframe_banner) {
             if (twitterAccount != getQueryStringByUrl(iframe_banner.src, 'twitterAccount')) {
                 iframe_banner.style.display = 'none'
-                // iframe_banner.src = chrome.runtime.getURL(`/iframe/group-card.html?twitterAccount=${twitterAccount}`)
+                // iframe_banner.src = chromeExtensionUrl + (`iframe/group-card.html?twitterAccount=${twitterAccount}`)
                 iframe_banner.contentWindow.postMessage({ actionType: 'SHOW_BANNER', twitterAccount }, '*');
             }
             return
@@ -1759,7 +1876,7 @@ const initGroupTip = () => {
             let iframe = document.createElement('iframe')
             iframe.id = 'denet_group_banner'
             iframe.style.cssText = 'border: medium none; display:none; width:100%; height:100px;'
-            iframe.src = chrome.runtime.getURL(`/iframe/group-card.html?twitterAccount=${twitterAccount}`)
+            iframe.src = chromeExtensionUrl + (`iframe/group-card.html?twitterAccount=${twitterAccount}`)
             // iframe.contentWindow.postMessage({ actionType: 'SHOW_BANNER', twitterAccount }, '*');
             if (dom && !dom.parentNode.children[0].querySelector('iframe')) {
                 // dom.parentNode.insertBefore(iframe, dom)
@@ -1790,7 +1907,7 @@ export const showBuyNFT = ({ nft_project_Id, post_Id = '' }) => {
     }
     let iframe = document.querySelector('#nftProjectId')
     iframe.style.display = 'block'
-    iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/?nftProjectId=${nft_project_Id}&postId=${post_Id}`)
+    iframe.src = chromeExtensionUrl + (`iframe/buy-nft.html#/?nftProjectId=${nft_project_Id}&postId=${post_Id}`)
 }
 
 const initBuyNFT = () => {
@@ -1809,7 +1926,7 @@ export const showNFTCard = () => {
     let where = isTwitter && userElem && tabIndex;
     if (where) {
         let iframe = document.createElement('iframe');
-        iframe.src = chrome.runtime.getURL(`/iframe/nft-card.html`)
+        iframe.src = chromeExtensionUrl + (`iframe/nft-card.html`)
         iframe.style.cssText = 'border:medium none; width:100%; height:290px;';
         let nftElement = document.createElement('div');
         nftElement.id = 'de-nft-node';
@@ -1850,7 +1967,7 @@ export const appendPopupPage = (params = {}) => {
 
     let iframe = document.createElement('iframe');
     iframe.id = 'de-popup-page';
-    iframe.src = chrome.runtime.getURL('/iframe/popup-page.html') + `#${path}`;
+    iframe.src = chromeExtensionUrl + ('iframe/popup-page.html') + `#${path}`;
     iframe.style.cssText = `border: medium none; width: 375px !important;
         height: 650px;position: fixed; right: 16px; top: 16px;background: #FFFFFF;border: 0.5px solid #919191;box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.2);box-sizing: border-box;z-index: 90000;
         animation-duration: 0.5s !important;
@@ -1897,7 +2014,7 @@ export const showPopupPage = (params = {}) => {
     }
     if (iframe) {
         if (path) {
-            iframe.src = chrome.runtime.getURL('/iframe/popup-page.html') + `#${path}`;
+            iframe.src = chromeExtensionUrl + ('iframe/popup-page.html') + `#${path}`;
         }
         iframe.style.transform = 'translateX(-' + 395 + 'px)';
 
@@ -2415,7 +2532,7 @@ const addTabGroupContent = (cb) => {
     }
     let iframe = document.createElement('iframe');
     iframe.id = 'de-tab-group-content';
-    iframe.src = `${iframeHost}/tab-group` + `?params=${JSON.stringify(params)}`;
+    iframe.src = getInnerIframeURL(`${iframeHost}/tab-group` + `?params=${JSON.stringify(params)}&iframeID=${iframe.id}`);
     iframe.style.cssText = `border: medium none; height: 500px;display: none`
 
     let iframeContent = getGroupTabContentNode();
@@ -2561,6 +2678,12 @@ export const setGroupInfo = (params = {}) => {
     }
 }
 
+export const getExtensionStorgeDataForIframe = (data) => {
+    getChromeStorage(data.key).then((res) => {
+        messageCenter.send(data.iframeID, `IFRAME_GET_EXTENSION_STORGE_DATA-${data.messageID}`, res)
+    });
+}
+
 const getSysTheme = () => {
     const themeMedia = window.matchMedia("(prefers-color-scheme: light)");
     if (themeMedia.matches) {
@@ -2621,3 +2744,16 @@ export const showPublishDialog = () => {
         smallBtn.click();
     }
 }
+
+// 获取推文发送回去
+export const sendContentByTwitterID = (tweet_Id) => {
+    // 获取内容
+    let txt = parseCard.getContentByTwitterId(tweet_Id)
+    // 发送
+    chrome.runtime.sendMessage({
+        actionType: "CONTENT_GET_TWEET_TXT", data: {
+            tweet_Id,
+            txt
+        }
+    })
+}

+ 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",
-    "denet_app_version_code": "20",
+    "version": "1.1.7.2",
+    "denet_app_version_code": "22",
     "background": {
         "service_worker": "/js/background.js"
     },

+ 2 - 1
src/uilts/chromeExtension.js

@@ -68,6 +68,7 @@ export function getChromeStorage(key = '', callback) {
 //     } catch {
 //     }
 // }
+export let chromeExtensionUrl = chrome.runtime.getURL('/')
 
 export function setChromeCookie({
     name,
@@ -118,7 +119,7 @@ export function removeChromeCookie(params, cb) {
     }
 }
 
-export function sendChromeTabMessage(params, callback) {
+export function sendCurrentTabMessage(params, callback) {
     try {
         chrome.tabs.getCurrent((tab) => {
             chrome.tabs.sendMessage(tab.id, params, callback);

+ 6 - 0
src/uilts/denet.js

@@ -0,0 +1,6 @@
+import Content from '@/uilts/messageCenter/messageContent'
+
+let denet = {}
+denet.content = Content
+
+export default denet

+ 55 - 0
src/uilts/help.js

@@ -1,3 +1,7 @@
+import { appVersionCode } from '@/http/configAPI.js'
+import FingerprintJS from '@fingerprintjs/fingerprintjs'
+var moment = require('moment')
+
 export function getQueryString(name) {
   let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
   let r = window.location.search.substr(1).match(reg);
@@ -110,6 +114,13 @@ export function getTargetElementWhenClick(e) {
   return result
 }
 
+export function setCookie(cname, cvalue, exdays) {
+  var d = new Date();
+  d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
+  var expires = "expires=" + d.toGMTString();
+  document.cookie = cname + "=" + cvalue + "; " + expires;
+}
+
 export function getCookie(name) {
   var strcookie = document.cookie; //获取cookie字符串
   var arrcookie = strcookie.split("; "); //分割
@@ -265,4 +276,48 @@ export function $(key, cache = true) {
     }
   }
   return _dom
+}
+
+export const getInnerIframeURL = (url) => {
+  let iframeUrl = url;
+  if (url.includes('?')) {
+    iframeUrl += `&appVersionCode=${appVersionCode}`;
+  } else {
+    iframeUrl += `?appVersionCode=${appVersionCode}`;
+  }
+  return iframeUrl;
+}
+
+export const getVisitorId = async () => {
+  const fpPromise = FingerprintJS.load();
+  let result = {};
+  const fp = await fpPromise
+  result = await fp.get();
+  return result;
+}
+
+export const getBeforeTimeFormat = (timestamp) => {
+  let _d1 = moment(new Date().getTime())
+  let _d2 = moment(timestamp)
+  const plural = (n, s) => {
+    let _str = `${n} ${s} ago`
+    if (n > 1) {
+      _str = `${n} ${s}s ago`
+    }
+    return _str
+  }
+  let _d = moment.duration(_d1.diff(_d2)).days()
+  if (_d) {
+    return plural(_d, 'day')
+  }
+  let _h = moment.duration(_d1.diff(_d2)).hours()
+  if (_h) {
+    return plural(_h, 'hour')
+  }
+  let _m = moment.duration(_d1.diff(_d2)).minutes()
+  if (_m) {
+    return plural(_m, 'min')
+  }
+  let _s = moment.duration(_d1.diff(_d2)).seconds()
+  return plural(_s, 'sec')
 }

+ 9 - 9
src/uilts/messageCenter/index.js

@@ -1,13 +1,13 @@
-class MessageCenter { 
-    constructor() { 
+class MessageCenter {
+    constructor() {
         this.iframeMap = new Map();
         this.messageCallbackMap = new Map();
         // this.listen()
     }
 
-    findIframeById(id) { 
+    findIframeById(id) {
         let target = this.iframeMap.get(id);
-        if (!target) { 
+        if (!target) {
             target = document.getElementById(id)
             this.iframeMap.set('id', target)
         }
@@ -27,17 +27,17 @@ class MessageCenter {
         let activeQuene = this.messageCallbackMap.get(actionType);
         if (activeQuene?.length > 0) {
             activeQuene.push(callback)
-        } else { 
+        } else {
             this.messageCallbackMap.set(actionType, [callback])
         }
     }
     // don't use
-    listen() { 
-        window.addEventListener('message', (e) => { 
+    listen() {
+        window.addEventListener('message', (e) => {
             const { actionType, data } = e.data;
             console.log('get message in content ...', actionType, data)
-            const quene = this.messageCallbackMap.get(actionType) ||  [];
-            while (quene.length > 0) { 
+            const quene = this.messageCallbackMap.get(actionType) || [];
+            while (quene.length > 0) {
                 let callback = quene.pop();
                 callback(data)
             }

+ 39 - 0
src/uilts/messageCenter/messageContent.js

@@ -0,0 +1,39 @@
+// class message  
+import messageCenter from '@/uilts/messageCenter';
+import MESSAGE_ENUM from "@/uilts/messageCenter/messageEnum";
+import { guid, iframeID } from '@/uilts/help.js'
+
+// content.createTweets('iframe') 
+
+// 做任务
+class doTask {
+    createTweet({ txt = '' }) {
+        return new Promise((res, rej) => {
+            messageCenter.send({
+                actionType: MESSAGE_ENUM.IFRAME_DO_TASK_CREATE_TWEET,
+                data: {
+                    iframeID,//用于告诉父窗口会传消息给哪个iframe 
+                    messageID: guid()// 唯一的ID,用于标记回调函数
+                },
+                info: {
+                    txt
+                },
+                callback: (data) => {
+                    res(data)
+                },
+                failback: (e) => {
+                    rej(e)
+                }
+            })
+        })
+        // console.log(window.parent.window.atest)
+        // window.postMessage({actionType: 'iframe_test', data: key})
+    }
+}
+
+
+export default {
+    doTask() {
+        return new doTask()
+    }
+}

+ 25 - 0
src/uilts/messageCenter/messageEnum.js

@@ -0,0 +1,25 @@
+/** 向父窗口发送的事件定义 */
+const SEND_MESSAGE_ENUM = {
+    IFREME_TAB_GROUP_SET_IFRAME_HEIGHT: 'IFREME_TAB_GROUP_SET_IFRAME_HEIGHT',
+    /** group tab 内的列表项点击 */
+    IFRAME_PAGE_JUMP: 'IFRAME_PAGE_JUMP',
+    IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP: 'IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP',
+    /** 获取content的localstorge数据 */
+    IFRAME_GET_EXTENSION_STORGE_DATA: 'IFRAME_GET_EXTENSION_STORGE_DATA',
+
+    // ---- 做任务 ----
+    IFRAME_DO_TASK_CREATE_TWEET: 'IFRAME_DO_TASK_CREATE_TWEET'
+
+}
+
+/** 接收父窗口的事件定义 */
+const RECEIVE_MESSAGE_ENUM = {
+    /** 切换到group tab */
+    CONTENT_REFRESH_TAB_GROUP_LIST: 'CONTENT_REFRESH_TAB_GROUP_LIST',
+    /** group打开时,页面发生滚动 */
+    CONTENT_GROUP_LIST_SCROLL: 'CONTENT_GROUP_LIST_SCROLL',
+    CONTENT_SEND_GROUP_NAV_TOP: 'CONTENT_SEND_GROUP_NAV_TOP',
+    CONTENT_SYS_THEME_CHANGE: 'CONTENT_SYS_THEME_CHANGE'
+}
+
+export default { ...SEND_MESSAGE_ENUM, ...RECEIVE_MESSAGE_ENUM }

+ 12 - 1
src/view/components/currency-list.vue

@@ -186,7 +186,18 @@ const searchCurrency = debounce(function (searchWords) {
     }).then(res => {
         if (res.code == 0) {
             if (res.data.currencyCategories && res.data.currencyCategories.length) {
-                let list = res.data.currencyCategories[0];
+                let currencyCategories = res.data.currencyCategories;
+
+                let arr = [];
+                for(let i = 0; i < currencyCategories.length; i++) {
+                  let item = currencyCategories[i];
+                  arr = arr.concat(item.data);
+                }
+
+                currencyCategories[0]['data'] = arr;
+
+                let list = currencyCategories[0];
+
                 if (list && list.data && list.data.length) {
                     searchList.value = list.data;
                 } else {

+ 6 - 5
src/view/components/custom-card-cover.vue

@@ -89,10 +89,10 @@
                 <img class="img" :src="data.currencyIconUrl" /> <span class="txt"> {{data.tokenSymbol}}  <template v-if="data.currencyCode != 'USD'">equivalent (Crypto)</template></span>
             </div>
 
-            <img class="img-treasure-big" :src="require('@/assets/img/icon-card-cover-treasure-big.png')">
+            <img class="img-treasure-big" :src="require('@/assets/img/icon-treasure-box.png')">
 
             <div class="treasure-row-4">
-               <img class="img" :src="require('@/assets/svg/icon-card-cover-treasure-tasks.svg')"> to Hunt Treasure
+               <img class="img" :src="require('@/assets/svg/icon-three-line.svg')"> to Hunt Treasure
             </div>
 
             <div class="open-btn" @click="open">
@@ -181,9 +181,9 @@ const props = defineProps({
 watch(() => props.show, (newVal) => {
       if(newVal) {
         zoomCom.value && zoomCom.value.setFontZoom(0);
-        zoomCom1.value && zoomCom.value.setFontZoom(0);
-        zoomCom2.value && zoomCom.value.setFontZoom(0);
-        zoomCom3.value && zoomCom.value.setFontZoom(0);
+        zoomCom1.value && zoomCom1.value.setFontZoom(0);
+        zoomCom2.value && zoomCom2.value.setFontZoom(0);
+        zoomCom3.value && zoomCom3.value.setFontZoom(0);
       }
     },
     {
@@ -377,6 +377,7 @@ onMounted(() => {
 
             .img {
                 width: 76px;
+                margin-right: 10px;
             }
         }
 

+ 20 - 8
src/view/components/custom-card-horizontal-cover.vue

@@ -37,7 +37,7 @@
             </div>
 
             <div class="content-text">
-                <template v-if="data.type != PlayType.treasure">
+                <div style="margin-left: 35px" v-if="data.type != PlayType.treasure">
                     <div class="title">
                         <span>{{data.currencyCode == 'USD' ? 'US Dollar' : data.tokenSymbol}} </span>
                         &nbsp;GIVEAWAY
@@ -64,7 +64,7 @@
                             {{data.totalCount}} WINNERS TO SHARE
                         </template>
                     </div>
-                </template>
+                </div>
                 <div class="treasure-layout" v-else>
                     <div class="treasure-row-1">
                         <span class="left">Treasure</span>
@@ -73,10 +73,12 @@
                         </component-zoom>
                     </div>
                     <div class="treasure-desc-data">
-                        <div class="item">
-                            <img class="icon"
-                                :src="require('@/assets/svg/icon-preview-trophy.svg')" />
-                            {{data.totalCount}} Winners
+                        <div class="item up-gain">
+                            You can get up to $
+                            <component-zoom :width="160"
+                            fontSize="24" :txt="data.upGainAmountUsdValue || 0">
+                              <div class="amount">{{data.upGainAmountUsdValue || 0}}</div>
+                            </component-zoom>
                         </div>
                         <div class="item">
                             <img class="icon" :src="data.currencyIconUrl">
@@ -215,7 +217,7 @@ watch(() => props.data, () => {
     .content-text {
         position: absolute;
         top: 53px;
-        left: 35px;
+        left: 0;
         .title {
             font-weight: 800;
             font-size: 16px;
@@ -272,6 +274,7 @@ watch(() => props.data, () => {
                 font-weight: 900;
                 font-size: 35px;
                 color: #fff;
+                margin-left: 35px;
 
                 .left {
                     margin-right: 7px;
@@ -286,7 +289,15 @@ watch(() => props.data, () => {
             }
 
             .treasure-desc-data {
-                margin-top: 18px;
+                margin-top: 12px;
+
+                .up-gain {
+                  background: linear-gradient(90deg, rgba(255, 255, 255, 0.1) 15.54%, rgba(255, 255, 255, 0) 100%);
+                  width: 350px;
+                  color: #fff !important;
+                  padding: 4px 0;
+                  box-sizing: border-box;
+                }
 
                 .item {
                     font-weight: 500;
@@ -295,6 +306,7 @@ watch(() => props.data, () => {
                     margin-bottom: 10px;
                     display: flex;
                     align-items: center;
+                    padding-left: 35px;
 
                     .icon {
                         width: 20px;

+ 12 - 9
src/view/content/message/index.vue

@@ -3,14 +3,16 @@
         <template v-for="item in state.list" :key="item.createTimestamp">
             <div class="denet-message-area" @click="clickItem(item)" v-if="item.bizType == 2">
                 <img :src="require('@/assets/img/icon-message-fail.png')" alt />
-                <span>You were not selected from {{item.bizData.twitterAccount}}'s giveaway events... Click to see more giveaways!</span>
+                <span>You were not selected from {{ item.bizData.twitterAccount }}'s giveaway events... Click to see more
+                    giveaways!</span>
                 <div class="denet-message-close" @click.stop="clickClose(item)">
                     <img :src="require('@/assets/img/icon-message-close.png')" alt />
                 </div>
             </div>
             <div class="denet-message-area" @click="clickItem(item)" v-if="item.bizType == 1">
                 <img :src="require('@/assets/img/icon-message-win.png')" alt />
-                <span>Congratulations! You won <b class="denet-message-money"> {{getPrize(item.bizData)}}</b> from {{item.bizData.twitterAccount}}'s giveaway!🎉</span>
+                <span>Congratulations! You won <b class="denet-message-money"> {{ getPrize(item.bizData) }}</b> from
+                    {{ item.bizData.twitterAccount }}'s giveaway!🎉</span>
                 <div class="denet-message-close" @click.stop="clickClose(item)">
                     <img :src="require('@/assets/img/icon-message-close.png')" alt />
                 </div>
@@ -35,16 +37,16 @@ let state = reactive({
 let timer, now_time
 
 // 获取奖励
-const getPrize = (item) => { 
+const getPrize = (item) => {
     const { lotteryMoney, lotteryTokenSymbol, twitterAccount, rewardType, customizedReward } = item;
     if (rewardType === RewardType.custom) {
         return customizedReward;
     } else {
-        return `${item.bizData.lotteryMoney} ${item.bizData.lotteryTokenSymbol}` 
+        return `${item.bizData.lotteryMoney} ${item.bizData.lotteryTokenSymbol}`
     }
 }
 
-// 过5秒消失逻辑
+// 过20秒消失逻辑
 const overTimeClose = () => {
     if (timer) {
         return
@@ -56,7 +58,7 @@ const overTimeClose = () => {
         }
         now_time = new Date().getTime()
         for (let i in state.list) {
-            if ((now_time - state.list[i].read_time) >= 5000) {
+            if ((now_time - state.list[i].read_time) >= 20000) {
                 state.list.splice(i, 1)
             }
         }
@@ -121,9 +123,10 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
 </script>
 
 <style lang="scss" >
-#denet_message{
+#denet_message {
     text-align: left;
 }
+
 .denet-message {
     position: fixed;
     max-height: 100%;
@@ -131,7 +134,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     top: 0;
     right: 0;
     width: 500px;
-    z-index: 9999;    
+    z-index: 9999;
     text-align: left;
 
     &-area {
@@ -147,7 +150,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
         margin-left: 129px;
         animation: right_to_left 1s;
         text-align: left;
-        
+
         img:first-child {
             width: 40px;
             height: 40px;

+ 27 - 18
src/view/iframe/buy-nft/buy/home.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="dialog"  :style="{'height': dialogStyle.height + 'px'}">
+    <div class="dialog" :style="{ 'height': dialogStyle.height + 'px' }">
         <!-- home -->
         <div class="area-title">
             <img :src="require('@/assets/svg/icon-close.svg')" @click="clickClose" />
@@ -16,11 +16,14 @@
             <!-- 首页 -->
             <div class="mark">
                 <div class="sold">SOLD: {{ state.data.itemSoldCount || 0 }}/{{ state.data.itemTotalCount || 0 }} </div>
-                <div class="limit" v-if="showDesc">Buy Limit: {{ state.data.userBuyCount || 0 }}/{{ state.data.perUserBuyLimit || 0 }}</div>
+                <div class="limit" v-if="showDesc">Buy Limit: {{ state.data.userBuyCount || 0 }}/{{
+                        state.data.perUserBuyLimit || 0
+                }}</div>
             </div>
             <div class="btn-area">
                 <!-- 兑换码 -->
-                <template v-if="(state.data.perUserBuyLimit - state.data.userBuyCount) >= 1 && (state.data.itemTotalCount - state.data.itemSoldCount) >= 1">
+                <template
+                    v-if="(state.data.perUserBuyLimit - state.data.userBuyCount) >= 1 && (state.data.itemTotalCount - state.data.itemSoldCount) >= 1">
                     <div class="redeem" @click="showRedeemLayer">Redeem</div>
                 </template>
                 <template v-else>
@@ -28,10 +31,7 @@
                 </template>
 
                 <template v-for="item in state.data.salePlans.slice(0, 2).reverse()">
-                    <div
-                        class="buy1"
-                        :class="{ grey: payNext }"
-                        @click="clickJump(item)"
+                    <div class="buy1" :class="{ grey: payNext }" @click="clickJump(item)"
                         v-if="item.itemCount == 1 && (state.data.perUserBuyLimit - state.data.userBuyCount) >= 1 && (state.data.itemTotalCount - state.data.itemSoldCount) >= 1">
                         <template v-if="(item.price.length + item.currencyInfo.tokenSymbol.length) > 30">
                             <div class="left">Buy 1</div>
@@ -66,10 +66,7 @@
                         </template>
                     </div>
 
-                    <div
-                        class="buy5"
-                        :class="{ grey: payNext }"
-                        @click="clickJump(item)"
+                    <div class="buy5" :class="{ grey: payNext }" @click="clickJump(item)"
                         v-if="item.itemCount == 5 && (state.data.perUserBuyLimit - state.data.userBuyCount) >= 5 && (state.data.itemTotalCount - state.data.itemSoldCount) >= 5">
                         <div class="left">Buy {{ item.itemCount }}</div>
 
@@ -120,7 +117,7 @@ import Report from "@/log-center/log"
 import { getQueryString } from "@/uilts/help";
 import { calcRechargePayAmount } from "@/http/account";
 import { getCurrencyInfoByCode } from "@/http/publishApi";
-import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
+import { sendCurrentTabMessage } from '@/uilts/chromeExtension.js';
 let postId = inject('post_Id');
 let pay_info = inject('pay_info');
 let router = useRouter()
@@ -228,7 +225,7 @@ const clickJump = (item) => {
 
 const setDialogStyle = () => {
     let clientHeight = window.innerHeight;
-    if(clientHeight >= 840) {
+    if (clientHeight >= 840) {
         dialogStyle.height = 800;
     } else {
         dialogStyle.height = clientHeight - 40;
@@ -253,7 +250,7 @@ const redeemPost = () => {
         let { code, data } = res;
         if (code == 0 && data) {
             pay_info.buy_items = data
-            sendChromeTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
+            sendCurrentTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
             router.push({ path: '/open_box' });
             // report
             Report.reportLog({
@@ -340,8 +337,8 @@ const hideRedeemLayer = () => {
 watchEffect(() => {
     let len = 16
     let str = redeemStr.value.replace(/[^a-zA-Z0-9]/g, '')
-        str = str.toUpperCase();
-        str = str.slice(0, len);
+    str = str.toUpperCase();
+    str = str.slice(0, len);
     // set
     redeemStr.value = str;
     redeemNext.value = str !== '' && str.length === len;
@@ -353,7 +350,7 @@ onMounted(() => {
     let nft_project_Id = router.currentRoute.value.query.nftProjectId
     let nft_group_Id = router.currentRoute.value.query.nft_group_Id
     let post_id = router.currentRoute.value.query.postId
-    if(nft_group_Id){
+    if (nft_group_Id) {
         pay_info.nft_group_Id = nft_group_Id
     }
     if (!nft_project_Id) {
@@ -556,8 +553,9 @@ onMounted(() => {
                 cursor: not-allowed;
                 border: unset;
                 color: #FFFFFF;
+
                 .usdt {
-                    color: #FFFFFF!important;
+                    color: #FFFFFF !important;
                 }
             }
 
@@ -576,6 +574,7 @@ onMounted(() => {
                 cursor: pointer;
                 margin-right: 12px;
                 box-sizing: border-box;
+
                 &.grey {
                     background: #CDCDCD;
                     cursor: not-allowed;
@@ -597,11 +596,13 @@ onMounted(() => {
     border-radius: 20px;
     background: #FFFFFF;
     transform: translate(-50%, -50%);
+
     .header {
         display: flex;
         align-items: center;
         height: 48px;
         box-shadow: 0px 0.5px 0px #D1D9DD;
+
         img {
             width: 24px;
             height: 24px;
@@ -609,8 +610,10 @@ onMounted(() => {
             cursor: pointer;
         }
     }
+
     .footer {
         padding: 20px;
+
         .tips {
             font-size: 16px;
             font-weight: 500;
@@ -618,6 +621,7 @@ onMounted(() => {
             letter-spacing: 0.3px;
             margin-bottom: 18px;
         }
+
         .input {
             display: flex;
             align-items: center;
@@ -626,6 +630,7 @@ onMounted(() => {
             border-radius: 100px;
             background: #FFFFFF;
             border: 1px solid #DDDDDD;
+
             input {
                 width: calc(100% - 40px);
                 border: 0;
@@ -635,9 +640,11 @@ onMounted(() => {
                 line-height: 19px;
             }
         }
+
         .confirm {
             margin-top: 45px;
             text-align: right;
+
             .btn {
                 border: 0;
                 width: 170px;
@@ -648,6 +655,7 @@ onMounted(() => {
                 font-weight: 700;
                 border-radius: 100px;
                 background: #1D9BF0;
+
                 &.grey {
                     background: #CDCDCD;
                     cursor: not-allowed;
@@ -658,6 +666,7 @@ onMounted(() => {
         }
     }
 }
+
 .redeemMask {
     position: absolute;
     z-index: 24;

+ 28 - 29
src/view/iframe/buy-nft/buy/pay.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="dialog" :style="{'height': dialogStyle.height + 'px'}">
+    <div class="dialog" :style="{ 'height': dialogStyle.height + 'px' }">
         <!-- home -->
         <div class="area-title">
             <img :src="require('@/assets/svg/icon-back.svg')" @click="clickBack" />
@@ -7,8 +7,7 @@
         </div>
         <!-- 内容 -->
         <div class="area-content">
-            <div
-                class="left"
+            <div class="left"
                 :class="{ auto: tempCurrentCurrencyInfo.currencyCode === 'USD' && Number(finalAmountData.rechargeAmountValue) <= 0 }">
                 <img :src="require('@/assets/img/img-box5.png')" v-show="pay_info.home.sale_plan.itemCount == 5"
                     alt="" />
@@ -22,8 +21,7 @@
                     </div>
                 </div>
             </div>
-            <div
-                class="right"
+            <div class="right"
                 :class="{ none: tempCurrentCurrencyInfo.currencyCode === 'USD' && Number(finalAmountData.rechargeAmountValue) <= 0 }">
                 <div class="card-content" v-if="tempCurrentCurrencyInfo.currencyCode">
                     <template v-if="tempCurrentCurrencyInfo.currencyCode !== 'USD'">
@@ -49,8 +47,7 @@
                             <img class="img" :src="require('@/assets/subject/top-01.svg')" />
                             <div class="font">Deposit to Send Giveaway</div>
                         </div>
-                        <payment-info-usd
-                            :finalAmountData="finalAmountData">
+                        <payment-info-usd :finalAmountData="finalAmountData">
                         </payment-info-usd>
                     </template>
                 </div>
@@ -104,19 +101,19 @@
                         <div class="desc">Balance</div>
                         <div class="price">
                             $
-                            {{tempCurrentCurrencyInfo.balance}}
+                            {{ tempCurrentCurrencyInfo.balance }}
                         </div>
                     </div>
-                    <img class="refresh"
-                        :class="{ 'icon-refresh-rotate': refreshRotate }"
-                        :src=" require('@/assets/svg/icon-form-refresh.svg')"
-                        @click="updateCurrencyBanlce"/>
+                    <img class="refresh" :class="{ 'icon-refresh-rotate': refreshRotate }"
+                        :src="require('@/assets/svg/icon-form-refresh.svg')" @click="updateCurrencyBanlce" />
                 </div>
                 <!-- Play -->
                 <div class="buy1 usd" @click="clickPayUSD">
                     <div class="left">Pay</div>
                     <div class="right">
-                        {{ finalAmountData.rechargeAmountValue > 0 ? finalAmountData.rechargeAmountValue : finalAmountData.orderAmountValue }}
+                        {{ finalAmountData.rechargeAmountValue > 0 ? finalAmountData.rechargeAmountValue :
+                                finalAmountData.orderAmountValue
+                        }}
                         {{ pay_info.home.sale_plan.currencyInfo.tokenSymbol }}
                     </div>
                 </div>
@@ -125,10 +122,7 @@
     </div>
 
     <!-- 预览页充值 -->
-    <message-box
-        :dialogVisible="showDepositMessageBox"
-        title="Is the Deposit Completed?"
-        @cancel="depositAchCancel"
+    <message-box :dialogVisible="showDepositMessageBox" title="Is the Deposit Completed?" @cancel="depositAchCancel"
         @confirm="depositAchConfirm">
     </message-box>
 </template>
@@ -145,10 +139,10 @@ import messageBox from "@/view/components/message-box.vue";
 import BtnLoading from '../components/btn-loading.vue'
 import { payNftMysteryBoxWithBalance } from "@/http/pay";
 import { calcRechargePayAmount } from "@/http/account";
-import { getChromeStorage, setChromeStorage } from "@/uilts/chromeExtension"
+import { getChromeStorage, setChromeStorage, chromeExtensionUrl } from "@/uilts/chromeExtension"
 import { ElMessage } from 'element-plus'
 import "element-plus/es/components/message/style/css";
-import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
+import { sendCurrentTabMessage } from '@/uilts/chromeExtension.js';
 
 let pay_info = inject('pay_info');
 let postId = inject('post_Id');
@@ -181,7 +175,7 @@ let dialogStyle = reactive({
 
 const calcRechPayAmount = async (params) => {
     let res = await calcRechargePayAmount({
-        params : params
+        params: params
     })
 
     if (res.code == 0) {
@@ -220,7 +214,7 @@ const clickPlay = () => {
         state.loading.show = false
         if (res.code == 0) {
             pay_info.buy_items = res.data.buyItems
-            sendChromeTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
+            sendCurrentTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
             router.push({ path: '/open_box' });
             Report.reportLog({
                 pageSource: Report.pageSource.nftShopPage,
@@ -285,17 +279,17 @@ const clickPlay = () => {
 }
 
 const clickPayUSD = () => {
-    if(Number(finalAmountData.value.rechargeAmountValue) > 0) {
+    if (Number(finalAmountData.value.rechargeAmountValue) > 0) {
         setTimeout(() => {
             showDepositMessageBox.value = true;
         }, 1000)
-        chrome.tabs.getCurrent(tab =>{
+        chrome.tabs.getCurrent(tab => {
             let achPayInfo = {
                 amountValue: finalAmountData.value.rechargeAmountValue,
                 tab: tab
             };
-            let guideUrl = chrome.runtime.getURL('/iframe/ach-cashier.html');
-            setChromeStorage({ achPayInfo : JSON.stringify(achPayInfo)});
+            let guideUrl = chromeExtensionUrl + ('iframe/ach-cashier.html');
+            setChromeStorage({ achPayInfo: JSON.stringify(achPayInfo) });
 
             chrome.tabs.create({
                 url: guideUrl
@@ -315,7 +309,7 @@ let tempCurrentCurrencyInfo = ref({});
 
 const refreshRotate = ref(false);
 const updateCurrencyBanlce = () => {
-    if(!refreshRotate.value) {
+    if (!refreshRotate.value) {
         refreshRotate.value = true;
         getCurrencyInfo()
         setTimeout(() => {
@@ -362,7 +356,7 @@ const amountInterval = () => {
 
 const setDialogStyle = () => {
     let clientHeight = window.innerHeight;
-    if(clientHeight >= 840) {
+    if (clientHeight >= 840) {
         dialogStyle.height = 800;
     } else {
         dialogStyle.height = clientHeight - 40;
@@ -460,7 +454,7 @@ onUnmounted(() => {
 
             .tip {
                 margin-top: 15px;
-                font-size: 16px;    
+                font-size: 16px;
                 display: flex;
                 justify-content: space-between;
 
@@ -480,7 +474,7 @@ onUnmounted(() => {
         .right {
             width: 400px;
             margin: 30px 56px 0px 30px;
-            
+
             &.none {
                 display: none;
             }
@@ -649,23 +643,28 @@ onUnmounted(() => {
 .balance {
     display: flex;
     margin-right: 20px;
+
     .icon {
         width: 40px;
         height: 40px;
     }
+
     .con {
         padding: 0 5px;
+
         .desc {
             color: rgba($color: #000000, $alpha: 0.5);
             font-size: 12px;
             margin-bottom: 4px;
         }
+
         .price {
             font-size: 14px;
             font-weight: bold;
             word-break: break-all;
         }
     }
+
     .refresh {
         width: 40px;
         cursor: pointer;

+ 2 - 2
src/view/iframe/buy-nft/group/tip.vue

@@ -52,7 +52,7 @@ import { reactive, onMounted } from 'vue'
 import { useRouter } from 'vue-router'
 import { setGroupJoin } from '@/http/group.js'
 import { ElMessage } from 'element-plus'
-import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
+import { sendCurrentTabMessage } from '@/uilts/chromeExtension.js';
 let state = reactive({
     show: 'tip',
     params: {}
@@ -70,7 +70,7 @@ const clickJoin = () => {
         if (res.code == 0) {
             state.show = 'success'
             state.params.type = 'buy'
-            sendChromeTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
+            sendCurrentTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
         } else {
             let msg = ''
             switch (String(res.code)) {

+ 11 - 11
src/view/iframe/group-card/card.vue

@@ -51,7 +51,7 @@ import { reactive, onBeforeMount } from 'vue'
 import { getTwitterNftGroupInfo } from "@/http/group";
 import { getQueryString } from '@/uilts/help.js';
 import Report from "@/log-center/log"
-import { sendChromeTabMessage, checkIsLogin } from '@/uilts/chromeExtension.js';
+import { sendCurrentTabMessage, checkIsLogin } from '@/uilts/chromeExtension.js';
 
 let state = reactive({
     show: 'arrow', //join
@@ -62,14 +62,14 @@ let state = reactive({
 
 // 显示加入小组弹框
 async function clickJoin() {
-    sendChromeTabMessage({ actionType: "SWITCH_GROUP_STATUS" }, () => { })
+    sendCurrentTabMessage({ actionType: "SWITCH_GROUP_STATUS" }, () => { })
     let _userInfo = await checkIsLogin()
     if (!_userInfo) {
         return
     }
     // 如果没购买过 弹出购买
     if (state.data.buyNftStatus == 0) {
-        sendChromeTabMessage({
+        sendCurrentTabMessage({
             actionType: "IFRAME_SHOW_JOIN_DIALOG",
             data: {
                 type: 'buy',
@@ -83,7 +83,7 @@ async function clickJoin() {
 
         // 如果购买过 没加入 显示加入按钮
     } else if (state.data.buyNftStatus == 1 && state.data.joinStatus == 0) {
-        sendChromeTabMessage({
+        sendCurrentTabMessage({
             actionType: "IFRAME_SHOW_JOIN_DIALOG",
             data: {
                 type: 'join',
@@ -140,7 +140,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
             } else {
                 state.show = state.show2
                 // console.log(11)
-                // sendChromeTabMessage({ actionType: "SWITCH_GROUP_STATUS", data: { type: 'btn' } }, () => { })
+                // sendCurrentTabMessage({ actionType: "SWITCH_GROUP_STATUS", data: { type: 'btn' } }, () => { })
             }
             break
     }
@@ -148,7 +148,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
 })
 
 chrome.storage.onChanged.addListener(changes => {
-    if (changes.userInfo) {
+    if (changes.userInfo && changes.userInfo.newValue) {
         let item = JSON.parse(changes.userInfo.newValue)
         if (item) {
             init()
@@ -184,7 +184,7 @@ const sendMessageToContent = (params) => {
     })
 }
 const clickArrow = () => {
-    sendChromeTabMessage({ actionType: "SWITCH_GROUP_STATUS" }, (res) => {
+    sendCurrentTabMessage({ actionType: "SWITCH_GROUP_STATUS" }, (res) => {
         if (!res) {
             Report.reportLog({
                 objectType: Report.objectType.chrome_extension_sendmessage_error
@@ -194,7 +194,7 @@ const clickArrow = () => {
 }
 
 async function clickPost() {
-    sendChromeTabMessage({ actionType: "SWITCH_GROUP_STATUS" }, (res) => {
+    sendCurrentTabMessage({ actionType: "SWITCH_GROUP_STATUS" }, (res) => {
         if (!res) {
             Report.reportLog({
                 objectType: Report.objectType.chrome_extension_sendmessage_error
@@ -207,7 +207,7 @@ async function clickPost() {
     }
     // 没有购买过
     if (state.data.buyNftStatus == 0) {
-        sendChromeTabMessage({
+        sendCurrentTabMessage({
             actionType: "IFRAME_SHOW_JOIN_DIALOG",
             data: {
                 type: 'buy',
@@ -220,7 +220,7 @@ async function clickPost() {
         })
         // 购买过 && 加入过
     } else if (state.data.buyNftStatus == 1 && state.data.joinStatus == 1) {
-        sendChromeTabMessage({
+        sendCurrentTabMessage({
             actionType: "IFRAME_SHOW_POST_DIALOG",
             data: {
                 groupId: state.data.nftGroupId
@@ -235,7 +235,7 @@ async function clickPost() {
 onBeforeMount(() => {
     state.twitterAccount = getQueryString('twitterAccount') || ''
     init(() => {
-        sendChromeTabMessage({ actionType: "IFRAME_SHOW_GROUP_TIP" })
+        sendCurrentTabMessage({ actionType: "IFRAME_SHOW_GROUP_TIP" })
     })
 
 })

+ 18 - 0
src/view/iframe/nft/card.vue

@@ -56,6 +56,7 @@ const isShare = ref(false);
 const isLoading = ref(true);
 const isShowGuide = ref(false);
 const nftProjectId = ref('');
+const nftAccount = ref('');
 let tweetId = ref('');
 
 const getSaleInfo = () => {
@@ -89,6 +90,7 @@ const getSaleData = (projectId) => {
 }
 
 const getSaleProjectInfo = (account) => {
+    nftAccount.value = account;
     getTwitterSaleNftProjectInfo({
         params: {
             twitterAccount: account
@@ -193,6 +195,22 @@ const msgListener = (req, sender, sendResponse) => {
 
 onMounted(() => {
     onRuntimeMsg();
+    // 切换用户
+    chrome.tabs.onUpdated.addListener((id, info) => {
+        if (info.status === "loading" && (info && info.url) && !isShare.value) {
+            let url = new URL(info.url);
+            let pathname = url.pathname;
+            let pathArr;
+            if (pathname) {
+                pathname = pathname.slice(1);
+                pathArr = pathname.split('/');
+                if (nftAccount.value !== pathArr[0]) {
+                    console.log(3333)
+                    getSaleInfo()
+                }
+            }
+        }
+    })
 })
 
 

+ 2 - 1
src/view/iframe/publish/components/get-more.vue

@@ -52,7 +52,8 @@ const jumpMore = () => {
       pageSource: props.reportData.pageSource,
       businessType: Report.businessType.buttonClick,
       objectType: Report.objectType.getMoreGiveaway,
-      postId: props.reportData.postId
+      postId: props.reportData.postId,
+      redPacketType: props.reportData.redPacketType
     });
     if (moreUrl.value) {
         window.open(moreUrl.value)

+ 13 - 21
src/view/iframe/publish/components/give-dialog-head.vue

@@ -4,35 +4,25 @@
             <!-- 关闭按钮 -->
             <div class="close-btn" @click="close">
                 <template v-if="publishType == 'TOOL_BOX'">
-                    <img  class="icon-close"
-                    :src="require('@/assets/svg/icon-close.svg')"
-                    v-if="toolBoxPageData.activePage == 'EDITOR'"/>
-                    <img class="icon-close"
-                        :src="require('@/assets/svg/icon-back.svg')"
-                        v-else/>
+                    <img class="icon-close" :src="require('@/assets/svg/icon-close.svg')"
+                        v-if="toolBoxPageData.activePage == 'EDITOR'" />
+                    <img class="icon-close" :src="require('@/assets/svg/icon-back.svg')" v-else />
                 </template>
                 <template v-else>
-                    <img  class="icon-close"
-                    :src="require('@/assets/svg/icon-close.svg')"
-                    v-if="showComType == 'default'"/>
-                    <img class="icon-close"
-                        :src="require('@/assets/svg/icon-back.svg')"
-                        v-else/>
+                    <img class="icon-close" :src="require('@/assets/svg/icon-close.svg')"
+                        v-if="showComType == 'default'" />
+                    <img class="icon-close" :src="require('@/assets/svg/icon-back.svg')" v-else />
                 </template>
             </div>
             <!-- 标题 -->
             <div class="title">
-                {{title}}
+                {{ title }}
             </div>
         </div>
         <div class="right">
             <!-- 更多按钮 -->
-            <img :src="require('@/assets/svg/icon-more-l.svg')"
-                class="more"
-                @click="showMoreOption = true">
-            <div class="area-option" 
-                v-if="showMoreOption" 
-                @click="showMoreOption = false">
+            <img :src="require('@/assets/svg/icon-more-l.svg')" class="more" @click="showMoreOption = true">
+            <div class="area-option" v-if="showMoreOption" @click="showMoreOption = false">
                 <div class="option">
                     <div class="item" @click="goTransactionsList()">
                         <img :src="require('@/assets/svg/icon-menu.svg')">
@@ -46,6 +36,7 @@
 
 <script setup>
 import { ref, defineEmits, defineProps } from "vue";
+import { chromeExtensionUrl } from "@/uilts/chromeExtension"
 
 const props = defineProps({
     publishType: {
@@ -76,7 +67,7 @@ const emits = defineEmits(["close"]);
 let showMoreOption = ref(false);
 
 const goTransactionsList = () => {
-    window.open(`${chrome.runtime.getURL('/iframe/home.html#/transactions')}`)
+    window.open(`${chromeExtensionUrl + ('iframe/home.html#/transactions')}`)
 }
 
 const close = () => {
@@ -98,6 +89,7 @@ const close = () => {
     .left {
         display: flex;
         align-items: center;
+
         .title {
             font-size: 16px;
             font-weight: 500;
@@ -161,7 +153,7 @@ const close = () => {
                 }
 
                 .item:hover {
-                        background: #F5F5F5;
+                    background: #F5F5F5;
                 }
             }
         }

+ 4 - 4
src/view/iframe/publish/components/giveaway-poster.vue

@@ -14,7 +14,7 @@
                             validityDuration: baseFormData.validityDuration,
                             customPosterUrl: customPosterInfo && customPosterInfo.before && customPosterInfo.before.imagePath || '',
                             userInfo: {
-                                nickName: userInfo.name,
+                                nickName: userInfo.nickName,
                                 avatarUrl: userInfo.avatarUrl
                             },
                             rewardType: baseFormData.rewardType,
@@ -65,7 +65,7 @@
                             validityDuration: baseFormData.validityDuration,
                             customPosterUrl: customPosterInfo && customPosterInfo.after && customPosterInfo.after.imagePath || '',
                             userInfo: {
-                                nickName: userInfo.name,
+                                nickName: userInfo.nickName,
                                 avatarUrl: userInfo.avatarUrl
                             },
                             rewardType: baseFormData.rewardType,
@@ -220,7 +220,7 @@ onMounted(() => {
     calcPreviewCanvasParams();
     getUserInfo((res) => {
         if(res) {
-            getUserName(res.nickName);
+            // getUserName(res.nickName);
         }
     });
     window.addEventListener('resize',function () {
@@ -354,4 +354,4 @@ onMounted(() => {
     top: unset;
     left: unset;
 }
-</style>
+</style>

+ 1 - 1
src/view/iframe/publish/components/nft-setting.vue

@@ -5,7 +5,7 @@
                 <div class="sel"><a-radio value="public"></a-radio></div>
                 <div class="inp">
                     <img :src=" require('@/assets/svg/icon-post-edit-open.svg') " />
-                    <span>Publick</span>
+                    <span>Public</span>
                 </div>
             </label>
             <label class="item">

+ 22 - 22
src/view/iframe/publish/components/pay-button.vue

@@ -1,13 +1,13 @@
 <template>
-<!-- pay 支付按钮 -->
+    <!-- pay 支付按钮 -->
     <div class="pay-wrapper">
         <slot name="balance"></slot>
         <div class="pay-btn">
-            <div class="iframe-pay"
-                v-show="currentCurrencyInfo.currencyCode == 'USD'">
-                <div class="token-pay"
-                    @click="clickPayUSD">
-                    Pay ${{finalAmountData.rechargeAmountValue > 0 && USDepositStatus != 'SUCCESS' ? finalAmountData.rechargeAmountValue : finalAmountData.orderAmountValue}}
+            <div class="iframe-pay" v-show="currentCurrencyInfo.currencyCode == 'USD'">
+                <div class="token-pay" @click="clickPayUSD">
+                    Pay ${{ finalAmountData.rechargeAmountValue > 0 && USDepositStatus != 'SUCCESS' ?
+                            finalAmountData.rechargeAmountValue : finalAmountData.orderAmountValue
+                    }}
                 </div>
 
                 <!-- <iframe
@@ -15,11 +15,9 @@
                     ref="iframe"
                     :src="`${payConfig.paypalHtml}?paypalClientId=${payConfig.paypalClientId}&amount=${props.finalAmountData.finalAmountValue}`"></iframe> -->
             </div>
-            <div class="token-pay"
-                :class="{ disabled: Number(currentCurrencyInfo.balance) < Number(payConfig.amount) }"
-                v-if="currentCurrencyInfo.currencyCode != 'USD'"
-                @click="balancePay">
-                Pay {{payConfig.amount || 0}} {{currentCurrencyInfo.tokenSymbol}}
+            <div class="token-pay" :class="{ disabled: Number(currentCurrencyInfo.balance) < Number(payConfig.amount) }"
+                v-if="currentCurrencyInfo.currencyCode != 'USD'" @click="balancePay">
+                Pay {{ payConfig.amount || 0 }} {{ currentCurrencyInfo.tokenSymbol }}
             </div>
         </div>
     </div>
@@ -30,9 +28,9 @@ import { onMounted, ref, defineProps, defineEmits, watch, defineExpose } from "v
 
 import { PlayType } from '@/types';
 
-import {payTaskLuckdropWithBalance} from "@/http/publishApi"
+import { payTaskLuckdropWithBalance } from "@/http/publishApi"
 import Report from "@/log-center/log"
-import {setChromeStorage, getChromeStorage} from "@/uilts/chromeExtension"
+import { setChromeStorage, getChromeStorage, chromeExtensionUrl } from "@/uilts/chromeExtension"
 
 const props = defineProps({
     finalAmountData: {
@@ -99,7 +97,7 @@ const balancePay = () => {
     }, {
         type: Report.getCurrentBizType(props.bizType)
     });
-    if(payIng) {
+    if (payIng) {
         return;
     }
     payIng = true;
@@ -109,8 +107,8 @@ const balancePay = () => {
             postId: props.payConfig.postId
         }
     }).then(res => {
-        if(res.code == 0) {
-            emits("payFinish", {...res.data});
+        if (res.code == 0) {
+            emits("payFinish", { ...res.data });
         }
         payIng = false;
     }).catch(() => {
@@ -119,17 +117,17 @@ const balancePay = () => {
 }
 
 const clickPayUSD = () => {
-    if(props.finalAmountData.rechargeAmountValue > 0 && props.USDepositStatus != 'SUCCESS') {
+    if (props.finalAmountData.rechargeAmountValue > 0 && props.USDepositStatus != 'SUCCESS') {
         setTimeout(() => {
             emits("showDepositMask", {});
         }, 1000)
-        chrome.tabs.getCurrent(tab =>{
+        chrome.tabs.getCurrent(tab => {
             let achPayInfo = {
                 amountValue: props.finalAmountData.rechargeAmountValue,
                 tab: tab
             };
-            let guideUrl = chrome.runtime.getURL('/iframe/ach-cashier.html');
-            setChromeStorage({ achPayInfo : JSON.stringify(achPayInfo)});
+            let guideUrl = chromeExtensionUrl + ('iframe/ach-cashier.html');
+            setChromeStorage({ achPayInfo: JSON.stringify(achPayInfo) });
 
             chrome.tabs.create({
                 url: guideUrl
@@ -203,13 +201,14 @@ defineExpose({
 
             .icon {
                 width: 14px;
-                margin-left:6px;
+                margin-left: 6px;
             }
 
             .desc {
-                margin-right:6px
+                margin-right: 6px
             }
         }
+
         .msg {
             font-size: 13px;
             color: #898989;
@@ -232,6 +231,7 @@ defineExpose({
             padding: 0 30px;
             word-break: break-all;
             cursor: pointer;
+
             &.disabled {
                 background: #DEDEDE;
             }

+ 3 - 2
src/view/iframe/publish/components/preview-card.vue

@@ -29,7 +29,7 @@
                             validityDuration: baseFormData.validityDuration,
                             customPosterUrl: customPosterInfo && customPosterInfo.after && customPosterInfo.after.imagePath || '',
                             userInfo: {
-                                nickName: userInfo.name,
+                                nickName: userInfo.nickName,
                                 avatarUrl: userInfo.avatarUrl
                             },
                             rewardType: baseFormData.rewardType,
@@ -74,11 +74,12 @@
                             customPosterUrl: customPosterInfo && customPosterInfo.before && customPosterInfo.before.imagePath || '',
                             addFans: baseFormData.addFans,
                             userInfo: {
-                                nickName: userInfo.name,
+                                nickName: userInfo.nickName,
                                 avatarUrl: userInfo.avatarUrl
                             },
                             rewardType: baseFormData.rewardType,
                             customizedReward: baseFormData.customizedReward,
+                            upGainAmountUsdValue: upGainAmountUsdValue
                         }">
                     </custom-card-horizontal-cover>
                 </div>

+ 80 - 16
src/view/iframe/publish/give-dialog.vue

@@ -309,9 +309,9 @@
                                         usdEstimateOrderAmount: treasureFormData.usdEstimateOrderAmount,
                                         upGainAmountUsdValue: treasureFormData.upGainAmountUsdValue,
                                         currencyIconUrl: currentCurrencyInfo.iconPath,
-                                        customPosterUrl: customPosterInfo && customPosterInfo.after && customPosterInfo.after.imagePath || '',
+                                        customPosterUrl: previewCustomPosterUrl,
                                         userInfo: {
-                                            nickName: userInfo.name,
+                                            nickName: userInfo.nickName,
                                             avatarUrl: userInfo.avatarUrl
                                         },
                                     }"></custom-card-cover>
@@ -455,6 +455,7 @@
 import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick, provide, computed } from "vue";
 import { postPublish, syncChainTokenRechargeRecord, getCurrencyInfoByCode, getUser } from "@/http/publishApi";
 import { getInviteGuildInfo, getInviteGuildInfoByOpenApi, saveInviteGuildInfo } from "@/http/discordApi";
+import { getPostEditorConfig } from "@/http/toolBoxApi";
 import { payCalcFee, getPayConfig } from "@/http/pay";
 import { upGainCalculate } from "@/http/treasureApi";
 import { getFrontConfig, calcRechargePayAmount } from "@/http/account";
@@ -490,6 +491,8 @@ import ComponentZoom from '@/view/components/component-zoom.vue'
 
 const config = {
     number: 'BigNumber',
+    precision: 64,            // Number of significant digits for BigNumbers
+    epsilon: 1e-60
 }
 const math = create(all, config);
 
@@ -538,7 +541,9 @@ let cropperType = ref('before')
 let customPosterInfo = ref({})
 let customPosterData = ref({})
 let customShowNewImage = ref(false)
-let refCropper = ref('')
+let refCropper = ref('');
+
+let previewCustomPosterUrl = ref('');
 
 // 当前展示组件内容 default(表单)  preview(预览)  topUp(充值)
 let showComType = ref("default");
@@ -829,6 +834,7 @@ watch(
             timer.value = setInterval(() => {
                 getCurrencyInfo({loop: true});
             }, 10000)
+            savePostEditorConfig();
         } else {
             clearInterval(timer.value);
         }
@@ -1166,6 +1172,10 @@ const submitRequest = async () => {
 
     let finishConditions = selectModeInfo.type != PlayType.treasure ? getFinishCondition() : getTreasureFinishCondition();
 
+    if(selectModeInfo.type == PlayType.treasure) {
+      customPosterData.value = {};
+    }
+
     let receiveConditions = openAntiBot.value ? "" : [];
 
     let validityDuration = '';
@@ -1240,8 +1250,11 @@ const submitRequest = async () => {
             showComType.value = "preview";
             previewFontSize.value = calcFontSize(baseFormData.amountValue, 238, 56);
             isBack.value = false;
-        } else {
-            console.log(res);
+        } else if(res.code == 2101){
+            const { usdPrice, minAmount, luckdropPostConfig = [] } = currentCurrencyInfo.value;
+            let currentLuckDropConfig = luckdropPostConfig.find(item => item.luckdropType === selectModeInfo.type);
+
+            message.warning(`The prize pool must be above $${currentLuckDropConfig.minTotalUsdAmount} and the average prize must be above $${currentLuckDropConfig.minAvgUsdAmount} per person.`);
         }
     })
     .catch((err) => {
@@ -1359,6 +1372,14 @@ const payStatusHandle = (payStatus) => {
     switch (payStatus) {
         case 1:
             emits("postPublishFinish", { publishRes });
+            Report.reportLog({
+              pageSource: Report.pageSource.previewPage,
+              businessType: Report.businessType.buttonClick,
+              objectType: Report.objectType.previewNextButton,
+              postId: publishRes.postId
+            }, {
+              type: Report.getCurrentBizType(selectModeInfo.type)
+            });
             showComType.value = "default";
             initParams();
             break;
@@ -1480,7 +1501,7 @@ const calcFansUnitAmount = () => {
         unitAmount = calcToken2UsdEstimate({amount: unitAmount, usdPrice: currentCurrencyInfo.value.usdPrice });
     }
 
-    return unitAmount;
+    return Math.floor(unitAmount * 1000) / 1000;
 };
 
 const setUpGainAmountUsdValue = (params) => {
@@ -1525,7 +1546,16 @@ const onUsdEstimateOrderAmountInput = () => {
 const onAmountInput = () => {
     let val = baseFormData.amountValue;
     // val = val.replace(/[^\d^\.]+/g, "");
-    val = String(val).replace(/^\D*(\d*(?:\.\d{0,18})?).*$/g, '$1');
+
+    let num = 2;
+    let minAmount = currentCurrencyInfo.value.minAmount;
+    let minArr = minAmount.split('.');
+    if(minArr && minArr.length > 1) {
+      num = minArr[1].length || 2;
+    }
+    let reg = new RegExp('^\\D*(\\d*(?:\\.\\d{0,'+num+'})?).*$', 'g');
+
+    val = String(val).replace(reg, '$1');
 
     const maxCount = baseFormData.rewardType === RewardType.money ? Number.MAX_SAFE_INTEGER : 100000000;
 
@@ -1638,12 +1668,15 @@ const calcIptValue = (cb) => {
         };
     }
 
-    if (math.format(math.evaluate(`${baseFormData.amountValue} / ${baseFormData.totalCount}`)) < +currentCurrencyInfo.value.minAmount) {
+    let val1 = +math.format(math.divide(math.bignumber(+baseFormData.amountValue), math.bignumber(+baseFormData.totalCount)));
+    let val2 = +math.format(math.divide(math.bignumber(+baseFormData.amountValue), math.bignumber(+currentCurrencyInfo.value.minAmount)));
+
+    if (val1 < +currentCurrencyInfo.value.minAmount) {
         flag = false;
     }
     return {
         flag,
-        count: Math.floor(math.format(math.evaluate(`${baseFormData.amountValue} / ${currentCurrencyInfo.value.minAmount}`)))
+        count: Math.floor(val2)
     }
 };
 
@@ -1662,11 +1695,19 @@ const checkUsdMinNumber = (isInTemplate) => {
             // 当前token允许的usd最小金额为0 或单个红包最小金额为0,则无限制
             return forbiddenText;
         } else {
-            const isAmountForbidden = currentLuckDropConfig?.minTotalUsdAmount ? math.format(math.evaluate(amountValue * usdPrice)) < currentLuckDropConfig.minTotalUsdAmount : false;
-            const isAvgForbidden = currentLuckDropConfig?.minAvgUsdAmount ? math.format(math.evaluate(amountValue / totalCount * usdPrice)) < currentLuckDropConfig.minAvgUsdAmount : false;
-            forbiddenText = isAmountForbidden && isAvgForbidden ?
+            let val1 = 0;
+            if(currentLuckDropConfig?.minAvgUsdAmount) {
+              val1 = +math.format(math.divide(math.bignumber(+amountValue), math.bignumber(+totalCount)));
+            }
+
+            const isAmountForbidden = currentLuckDropConfig?.minTotalUsdAmount ? +math.format(math.multiply(math.bignumber(+amountValue), math.bignumber(usdPrice))) < currentLuckDropConfig.minTotalUsdAmount : false;
+
+            const isAvgForbidden = currentLuckDropConfig?.minAvgUsdAmount ? +math.format(math.multiply(math.bignumber(val1), math.bignumber(usdPrice))) < currentLuckDropConfig.minAvgUsdAmount : false;
+
+
+            forbiddenText = isAmountForbidden || isAvgForbidden ?
                             `The prize pool must be above ${isInTemplate ? ('<span class="font-color-1D9BF0">$' + currentLuckDropConfig.minTotalUsdAmount + '</span>') : ('$' + currentLuckDropConfig.minTotalUsdAmount)}
-                            or the average prize must be above
+                            and the average prize must be above
                             ${isInTemplate ? ('<span class="font-color-1D9BF0">$' + currentLuckDropConfig.minAvgUsdAmount +' per person.</span>' ): ('$' + currentLuckDropConfig.minAvgUsdAmount + ' per person.') }`
                             : '';
         }
@@ -1689,8 +1730,7 @@ const checkTreasureAmountRange = (isInTemplate) => {
             let txt =  `The prize pool must be above ${isInTemplate ? ('<span class="font-color-1D9BF0">$' + currentLuckDropConfig.minTotalUsdAmount + '</span>') : ('$' + currentLuckDropConfig.minTotalUsdAmount)}
                             and the average prize must be above
                             ${isInTemplate ? ('<span class="font-color-1D9BF0">$' + currentLuckDropConfig.minAvgUsdAmount +' per person.</span>' ): ('$' + currentLuckDropConfig.minAvgUsdAmount + ' per person.') }`
-
-            const isAmountForbidden = currentLuckDropConfig?.minTotalUsdAmount ? +math.format(math.evaluate(baseFormData.amountValue * usdPrice)) < currentLuckDropConfig?.minTotalUsdAmount : false;
+            const isAmountForbidden = currentLuckDropConfig?.minTotalUsdAmount ? +math.format(math.multiply(math.bignumber(+baseFormData.amountValue), math.bignumber(usdPrice))) < currentLuckDropConfig?.minTotalUsdAmount : false;
 
             const isAvgForbidden = treasureFormData.fansUnitAmount !== '' && currentLuckDropConfig?.minAvgUsdAmount ? treasureFormData.fansUnitAmount < minAmount || treasureFormData.fansUnitAmount < currentLuckDropConfig?.minAvgUsdAmount : false;
 
@@ -2075,7 +2115,7 @@ const getUserName = (screenName) => {
 const getLocalCurrencyInfoByCode = async () => {
     let storageUserInfo = await getChromeStorage('userInfo') || {};
     userInfo.value = storageUserInfo;
-    getUserName(storageUserInfo.nickName);
+    // getUserName(storageUserInfo.nickName);
     if(!currentCurrencyInfo.value.currencyCode) {
         getCurrencyInfo();
     }
@@ -2135,8 +2175,11 @@ const selectPublishMode = (params, index) => {
         baseFormData.rewardType = RewardType.money;
         baseFormData.customizedReward = '';
         showGeneralLottery.value = false;
+        previewCustomPosterUrl.value = '';
+        treasureFormData.fansUnitAmount = calcFansUnitAmount();
     } else {
         showGeneralLottery.value = true;
+        previewCustomPosterUrl.value = customPosterInfo.value && customPosterInfo.value.after && customPosterInfo.value.after.imagePath || ''
     }
 
     onIptSetErrorTxt();
@@ -2158,6 +2201,14 @@ const onToolBoxPageChange = (params) => {
 
 const toolBoxPublishFinish = (params) => {
     toolBoxPageData.activePage = 'EDITOR';
+    Report.reportLog({
+      pageSource: Report.pageSource.previewPage,
+      businessType: Report.businessType.buttonClick,
+      objectType: Report.objectType.previewNextButton,
+      postId: params.publishRes.postId
+    }, {
+      type: Report.getCurrentBizType(PlayType.postEditor)
+    });
     emits("postPublishFinish", { publishRes: params.publishRes });
 }
 
@@ -2234,6 +2285,7 @@ const successImage = (data) => {
 const confirmData = (data) => {
     close()
     customPosterData.value = customPosterInfo.value;
+    previewCustomPosterUrl.value =  customPosterInfo.value && customPosterInfo.value.after && customPosterInfo.value.after.imagePath || ''
 }
 /**
  * 显示通用奖品名称编辑框
@@ -2322,11 +2374,22 @@ const onPageVisbile = () => {
     });
 }
 
+const savePostEditorConfig = () => {
+  getPostEditorConfig({
+    params: {}
+  }).then(res => {
+    if(res.code == 0 && res.data) {
+      setChromeStorage({ postEditorConfig : JSON.stringify(res.data)})
+    }
+  })
+}
+
 onMounted(() => {
     setFrontConfig();
     setPayConfig();
     getLocalCurrencyInfoByCode();
     onPageVisbile();
+    savePostEditorConfig();
     window.addEventListener('resize', function () {
         setDialogStyle(true);
     })
@@ -2489,6 +2552,7 @@ onMounted(() => {
 
                     .form-left-sheet {
                         width: 500px;
+                        height: max-content;
                     }
 
                     .form-right-sheet {

+ 55 - 77
src/view/iframe/publish/tool-box/child/editor.vue

@@ -23,7 +23,7 @@
           <div class="app-list">
             <div class="app" v-for="(app, idx) in historyList" :key="idx" @click="clickHistoryAppHandler(app)">
               <div class="img-wrapper">
-                <img class="img" :class="{ 'small-img': !app.appId }" :src="app.iconPath" :onerror="imgOnError" />
+                <img class="img" :class="{ 'small-img': !app.appId && !app.contentType }" :src="app.iconPath" :onerror="imgOnError" />
               </div>
               <div class="name">
                 {{ app.name }}
@@ -51,10 +51,9 @@
 
 <script setup>
 import { ref, defineProps, defineEmits, onMounted } from "vue";
-import axios from 'axios';
 import Report from "@/log-center/log"
 import { message } from "ant-design-vue";
-import { convertUrl, getAllPostEditorAppData, checkInputUrlInBlacklist } from "@/http/toolBoxApi";
+import { getAllPostEditorAppData, checkInputUrlInBlacklist } from "@/http/toolBoxApi";
 import { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
 import { checkURL, debounce } from "@/uilts/help"
 
@@ -78,9 +77,6 @@ let appList = ref();
 const emits = defineEmits(["changeShowCom"]);
 
 const searchHandler = async (_params) => {
-  let siteTitle = '', favicon = '';
-  let timer = null;
-
   // report
   Report.reportLog({
     pageSource: Report.pageSource.publisherDialog,
@@ -96,35 +92,26 @@ const searchHandler = async (_params) => {
 
   siteUrl.value = siteUrl.value.trim();
 
+  let postEditorConfig  = await getChromeStorage('postEditorConfig') || {};
+
   if (!checkURL(siteUrl.value)) {
     message.info('Incorrect URL entered');
     //提示
     return;
   }
-  const loadingHide = message.loading('loading...', 0);
-  timer = setTimeout(() => {
-    loadingHide();
-    message.error('Page loading failed');
-  }, 1000 * 15);
-
-  if(!_params) {
-    let blackListRes = await checkInputUrlInBlacklist({
-      params: {
-        url: siteUrl.value
-      }
-    })
 
-    if(blackListRes.code == 0) {
-      if(blackListRes.data) {
-        loadingHide();
-        clearTimeout(timer);
-        message.info('This site is not supported');
-        return;
+  if (!_params) {
+    if(postEditorConfig.inputUrlBlackList && postEditorConfig.inputUrlBlackList.length) {
+      for(let i = 0; i < postEditorConfig.inputUrlBlackList.length; i++) {
+        let url =  postEditorConfig.inputUrlBlackList[i];
+        if(siteUrl.value.startsWith(url)) {
+          message.info('This site is not supported');
+          return;
+        }
       }
     }
   }
 
-  let siteRes = await axios.get(siteUrl.value);
 
   let currentApp = {
     appId: '',
@@ -137,61 +124,28 @@ const searchHandler = async (_params) => {
     linkImagePath: '',
     name: '',
   }
+  let urlObj = new URL(siteUrl.value);
 
-  if (siteRes) {
-    if (siteRes.headers['content-type'].indexOf('text/html') < 0 || siteRes.request.status > 403) {
-      loadingHide();
-      message.error('Page loading failed');
-      return;
-    }
-    let urlObj = new URL(siteUrl.value);
-    if (siteRes.data) {
-      siteTitle = getTitleByHtmlStr(siteRes.data);
-      if (!siteTitle) {
-        siteTitle = urlObj.hostname;
-        currentApp.defaultTit = siteTitle;
-      }
-      currentApp.name = siteTitle;
-    }
-    favicon = urlObj.origin + '/favicon.ico';
-  }
-  currentApp.iconPath = favicon;
+  currentApp.iconPath = urlObj.origin + '/favicon.ico';
 
-  if(_params) {
+  if (_params) {
     currentApp = _params;
   }
-  
-  let convertRes = await convertUrl({ params: { originUrl: siteUrl.value } });
-  let params = { convertUrl: siteUrl.value, 
-                  originUrl: siteUrl.value, 
-                  appId: currentApp.appId, 
-                  linkImagePath: currentApp.linkImagePath, 
-                  currentApp };
-
-  loadingHide();
-  clearTimeout(timer);
-
-  if (convertRes && convertRes.code == 0) {
-    let { convertUrl } = convertRes.data || {};
-    params.convertUrl = convertUrl;
-  }
-  emits('changeShowCom', params)
-}
 
-const getTitleByHtmlStr = (str = '') => {
-  let tag_start = '<title>'
-  let tag_end = '</title>'
-  let index1 = str.indexOf(tag_start) + tag_start.length;
-  let index2 = str.indexOf(tag_end);
+  let siteConvertUrl = getConvertUrl({postEditorConfig, siteUrl: siteUrl.value});
 
-  if (index1 < tag_start.length || index2 < 0 || index2 < index1) {
-    return '';
-  }
+  let params = {
+    convertUrl: siteConvertUrl || siteUrl.value,
+    originUrl: siteUrl.value,
+    appId: currentApp.appId,
+    linkImagePath: currentApp.linkImagePath,
+    currentApp
+  };
 
-  return str.substring(index1, index2) || '';
-};
+  emits('changeShowCom', params)
+}
 
-const clickHistoryAppHandler =  debounce(function(params) {
+const clickHistoryAppHandler = debounce(function (params) {
   if (params.appId) {
     clickAppHandler(params, false);
   } else {
@@ -209,7 +163,7 @@ const clickHistoryAppHandler =  debounce(function(params) {
   });
 }, 800);
 
-const clickAppHandler =  debounce(function(params, isReport = true) {
+const clickAppHandler = debounce(function (params, isReport = true) {
   let { createType, defaultUrl, appId, linkImagePath } = params;
   switch (createType) {
     case 1:
@@ -253,10 +207,11 @@ const createGuideWindow = (params, isUpdate = false) => {
   openWindowList = [];
   selectAppGuideData = {};
 
-  let windowWith = window.screen.width - 500;
+  let windowWith = window.screen.width > 800 ? window.screen.width - 500 : 500;
   let guideUrl = chrome.runtime.getURL('/iframe/tool-box-guide.html');
 
-  setChromeStorage({ selectGuideApp : JSON.stringify(params)}, async () => {
+  setChromeStorage({ selectGuideApp: JSON.stringify(params) }, async () => {
+    console.log(windowWith, 'window', window)
     let window1 = await chrome.windows.create({
       width: windowWith,
       type: 'normal',
@@ -269,12 +224,12 @@ const createGuideWindow = (params, isUpdate = false) => {
       width: 500,
       type: 'popup',
       url: guideUrl,
-      left: windowWith,
+      left: window.screen.availLeft > 0 ? windowWith : window.screen.availLeft + windowWith,
       state: 'normal'
     })
     openWindowList.push(window2);
 
-    setChromeStorage({ guideAppWindowList: JSON.stringify({list: openWindowList})});
+    setChromeStorage({ guideAppWindowList: JSON.stringify({ list: openWindowList }) });
 
     // report
     Report.reportLog({
@@ -297,6 +252,29 @@ const getAppList = () => {
   })
 }
 
+const getConvertUrl = (params) => {
+  let {postEditorConfig = {}, siteUrl} = params;
+  const urlConvertConfigList = postEditorConfig.urlConvertConfigList || [];
+  let convertUrl = siteUrl;
+  if(urlConvertConfigList && urlConvertConfigList.length) {
+    for(let i = 0; i < urlConvertConfigList.length; i++) {
+      let urlPattern = urlConvertConfigList[i]['urlPattern'];
+      let reg = new RegExp(urlPattern);
+      let regMatch = siteUrl.match(reg);
+      if(regMatch && regMatch.length) {
+        let count = regMatch.length;
+        let urlConvertFormat = urlConvertConfigList[i]['urlConvertFormat'];
+        for(let j = 1; j < count; j++) {
+          urlConvertFormat = urlConvertFormat.replace(`{group${j}}`, regMatch[j])
+        }
+        convertUrl = urlConvertFormat;
+        break;
+      }
+    }
+  }
+
+  return convertUrl;
+}
 
 const onRuntimeMsg = () => {
   chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {

+ 105 - 12
src/view/iframe/publish/tool-box/child/preview.vue

@@ -49,9 +49,7 @@
                                     {{ previewData.currentApp.linkTitle }}
                                 </template>
                                 <template v-else>
-                                    {{ previewData.currentApp.defaultTit ? defaultLinkTitle :
-                                            previewData.currentApp.name
-                                    }}
+                                    {{ resourceInfo.title }}
                                 </template>
                             </div>
                         </div>
@@ -127,22 +125,60 @@ const props = defineProps({
     hasNft: {
         type: Boolean,
         default: false
+    },
+    resourceInfo: {
+        type: Object,
+        default: () => {
+          return {}
+        }
+    },
+    contentTypeConfig: {
+        type: Object,
+        default: () => {
+          return {
+
+          }
+        }
     }
 })
 
 watch(() => props.screenshotWebsiteData,
     (newVal) => {
         let { appId } = props.previewData;
-        if (loadingHide && (!appId || appId && !props.previewData.linkImagePath) && (newVal.url || newVal.status)) {
-            loadingHide();
-            loadingHide = null;
-            submitPublish();
+        if (loadingHide && (!appId || appId && !props.previewData.linkImagePath) && newVal.status) {
+                console.log(props.resourceInfo, 'resourceInfo')
+            if(appId) {
+              loadingHide();
+              loadingHide = null;
+              submitPublish();
+            } else {
+              if(props.resourceInfo.isSet) {
+                loadingHide();
+                loadingHide = null;
+                submitPublish();
+              }
+            }
         }
     },
     {
         deep: true
     })
 
+watch(() => props.resourceInfo,
+    (newVal) => {
+      console.log(newVal, 'resourceInfo')
+      let { appId } = props.previewData;
+      if (!appId && loadingHide && newVal.isSet && props.screenshotWebsiteData.status) {
+        loadingHide();
+        loadingHide = null;
+        submitPublish();
+      }
+    },
+    {
+        deep: true
+    })
+
+
 watch(() => props.showCom,
     (newVal) => {
         if (newVal == 'EDITOR' && loadingHide) {
@@ -210,11 +246,16 @@ const publishHandler = () => {
     if (loadingHide) {
         return;
     }
-    if ((!appId || appId && !props.previewData.linkImagePath) && (!props.screenshotWebsiteData.url && !props.screenshotWebsiteData.status)) {
+    if ((!appId || appId && !props.previewData.linkImagePath) && !props.screenshotWebsiteData.status) {
         loadingHide = message.loading('loading...', 0);
         return;
     }
 
+    if (!appId && !props.resourceInfo.isSet) {
+      loadingHide = message.loading('loading...', 0);
+      return;
+    }
+
     submitPublish();
 }
 
@@ -225,16 +266,50 @@ const submitPublish = () => {
         return;
     }
 
-    setHistoryData(currentApp);
+    if(!appId) {
+        let allowContentTypes = props.contentTypeConfig.allowContentTypes || [];
+        let isSupport = false;
+
+        if(props.resourceInfo.loadSuccess) {
+          for(let i = 0; i< allowContentTypes.length; i++){
+            let idx = props.resourceInfo.contentType.indexOf(allowContentTypes[i]);
+            if(idx > -1) {
+              isSupport = true;
+              break;
+            }
+          }
+        } else {
+          message.error('Page loading failed');
+          return;
+        }
+
+        if(!isSupport) {
+          message.warning(props.contentTypeConfig.unSupportToast);
+          return;
+        }
+    }
 
-    let linkTitle = currentApp.name ? currentApp.name : currentApp.defaultTit;
+    let linkTitle = props.resourceInfo.title;
+
+    let appData = {
+      ...currentApp
+    }
+    if(!props.resourceInfo.hasTitle) {
+      let contentType = props.resourceInfo.contentType || '';
+      appData.iconPath = props.screenshotWebsiteData.viewBgImageFullPath;
+      appData.contentType = contentType;
+      linkTitle = contentType ? getResourceTitle({contentType}) : '';
+    }
+
+    setHistoryData(appData, {linkTitle: !appId ? linkTitle : '' });
 
     let postBizData = {
         convertUrl,
         originUrl,
         appId,
         linkTitle: !appId ? linkTitle : '',
-        linkImagePath: props.screenshotWebsiteData.url
+        linkImagePath: props.screenshotWebsiteData.url,
+        viewBgImagePath: props.screenshotWebsiteData.viewBgImagePath
     };
     if (props.certNftProjectId !== '') {
         postBizData['certNftProjectId'] = props.certNftProjectId;
@@ -263,6 +338,7 @@ const submitPublish = () => {
     postPublish(data).then((res) => {
         subLoadingHide();
         submitIng.value = false;
+        subLoadingHide();
         if (res.code == 0) {
             let publishRes = res.data;
             emits("publishFinish", { publishRes });
@@ -275,9 +351,26 @@ const submitPublish = () => {
     });
 }
 
-const setHistoryData = async (params) => {
+const getResourceTitle = (params) => {
+  let {contentType} = params;
+  let contentTypeTitleMap = props.contentTypeConfig.contentTypeTitleMap || {};
+  let title = ''
+  for (let key in contentTypeTitleMap) {
+    if(contentType.indexOf(key) > -1) {
+      title = contentTypeTitleMap[key];
+      break;
+    }
+  }
+  return title;
+}
+
+const setHistoryData = async (params, {linkTitle = ''}) => {
     const maxLength = 9;
     let { list = [] } = await getChromeStorage('toolBoxAppHistoryData') || {};
+    if (linkTitle) {
+      params.name = linkTitle;
+    }
+
     if (list.length) {
         let hasSite = list.find(item => item.defaultUrl == params.defaultUrl);
         if (hasSite) {

+ 90 - 5
src/view/iframe/publish/tool-box/index.vue

@@ -8,6 +8,8 @@
             :defaultLinkTitle="pageData.defaultLinkTitle"
             :certNftProjectId="certNftProjectId"
             :hasNft="hasNft"
+            :resourceInfo="resourceInfo"
+            :contentTypeConfig="contentTypeConfig"
             @publishFinish="publishFinish">
             <nft-setting ref="nftSettingDom" @change="changeSetting"></nft-setting>
         </preview>
@@ -15,9 +17,9 @@
 </template>
 
 <script setup>
-import { ref, reactive, watch, defineProps, defineEmits } from "vue";
-
-import { screenshotWebsite } from "@/http/toolBoxApi";
+import { ref, reactive, watch, defineProps, defineEmits, onMounted } from "vue";
+import axios from 'axios';
+import { screenshotWebsite, getContentTypeConfig } from "@/http/toolBoxApi";
 import editor from '@/view/iframe/publish/tool-box/child/editor.vue'
 import preview from '@/view/iframe/publish/tool-box/child/preview.vue'
 import Report from "@/log-center/log"
@@ -71,12 +73,29 @@ let certNftProjectId = ref('')
 
 let screenshotWebsiteData = reactive({
     url: '',
+    viewBgImagePath: '',
+    viewBgImageFullPath: '',
     status: '',
 });
 
 let nftSettingDom = ref(null);
 let hasNft = ref(false);
 
+let contentTypeConfig = ref({
+  allowContentTypes: [],
+  unSupportToast: '',
+  contentTypeTitleMap: {}
+})
+
+let resourceInfo = ref({
+  isSet: false,
+  contentType: '',
+  statusCode: '',
+  title: '',
+  hasTitle: false,
+  loadSuccess: false
+});
+
 const changeShowCom = (params) => {
     showCom.value = 'PREVIEW';
     previewData.convertUrl = params.convertUrl;
@@ -86,7 +105,19 @@ const changeShowCom = (params) => {
     previewData.currentApp = params.currentApp || {};
 
     screenshotWebsiteData.url = '';
+    screenshotWebsiteData.viewBgImagePath = '';
+    screenshotWebsiteData.viewBgImageFullPath = '';
     screenshotWebsiteData.status = '';
+
+    resourceInfo.value = {
+      isSet: false,
+      contentType: '',
+      statusCode: '',
+      title: '',
+      hasTitle: false,
+      loadSuccess: false
+    };
+
     if(!params.appId || params.appId && !params.linkImagePath) {
         screenshotWebsite({
             params: {
@@ -96,8 +127,10 @@ const changeShowCom = (params) => {
             if(showCom.value != 'PREVIEW') {
                 return;
             }
-            if(res.code == 0) {
-                screenshotWebsiteData.url = res.data;
+            if(res.code == 0 && res.data) {
+                screenshotWebsiteData.url = res.data.linkImagePath;
+                screenshotWebsiteData.viewBgImagePath = res.data.viewBgImagePath;
+                screenshotWebsiteData.viewBgImageFullPath = res.data.viewBgImageFullPath;
                 screenshotWebsiteData.status = 1;
             } else {
                 screenshotWebsiteData.status = 1;
@@ -110,9 +143,52 @@ const changeShowCom = (params) => {
         })
     }
 
+    if(!params.appId) {
+      getResourceInfo({url:params.convertUrl});
+    }
+
     emits("onPageChange", {page: showCom.value});
 }
 
+const getResourceInfo = ({url}) => {
+  axios.get(url).then(res => {
+    if(res) {
+      resourceInfo.value.isSet = true;
+      resourceInfo.value.contentType = res.headers['content-type'];
+      resourceInfo.value.statusCode = res.request.status;
+      resourceInfo.value.hasTitle = resourceInfo.value.contentType.indexOf('text/html') > -1 ? true : false;
+      resourceInfo.value.loadSuccess = true;
+
+      let siteTitle = '';
+      if(resourceInfo.value.hasTitle) {
+        siteTitle = getTitleByHtmlStr(res.data);
+        if (!siteTitle) {
+          let urlObj = new URL(url);
+          siteTitle = urlObj.hostname;
+        }
+      }
+      resourceInfo.value.title = siteTitle;
+    }
+
+  }).catch(err => {
+    resourceInfo.value.isSet = true;
+  })
+}
+
+const getTitleByHtmlStr = (str = '') => {
+  let tag_start = '<title>'
+  let tag_end = '</title>'
+  let index1 = str.indexOf(tag_start) + tag_start.length;
+  let index2 = str.indexOf(tag_end);
+
+  if (index1 < tag_start.length || index2 < 0 || index2 < index1) {
+    return '';
+  }
+
+  return str.substring(index1, index2) || '';
+};
+
+
 const publishFinish = (params) => {
     emits("toolBoxPublishFinish", params);
 }
@@ -121,6 +197,15 @@ const changeSetting = (id = '') => {
     certNftProjectId.value = id;
 }
 
+onMounted(() => {
+  getContentTypeConfig({
+    params: {}
+  }).then(res => {
+    if(res.code == 0) {
+      contentTypeConfig.value = res.data;
+    }
+  })
+})
 </script>
 
 <style lang="scss" scoped>

+ 25 - 22
src/view/iframe/red-packet/luck-draw.vue

@@ -200,9 +200,11 @@
                     </div>
                 </div>
             </div>
-            <get-more :reportData="{pageSource: Report.pageSource.received_success_page,
-                                    postId: state.postId
-                                    }"></get-more>
+            <get-more :reportData="{
+                pageSource: Report.pageSource.received_success_page,
+                postId: state.postId,
+                redPacketType: Report.redPacketType.lottery
+            }"></get-more>
         </div>
 
 
@@ -237,7 +239,7 @@
                 validityDuration: state.count_down_time,
                 countDown: state.count_down_time,
                 userInfo: {
-                    nickName: state.detail.postUserInfo.name,
+                    nickName: state.detail.postUserInfo.nickName,
                     avatarUrl: state.detail.postUserInfo.avatarUrl
                 },
                 rewardType: state.detail.rewardType,
@@ -264,9 +266,7 @@
                         <a-tooltip :title="state.detail.amountValue">
                             {{ getBit(state.detail.amountValue) || '' }}
                         </a-tooltip>
-                    </span> {{
-                            state.detail.currencySymbol || ''
-                    }}
+                    </span> {{ state.detail.currencySymbol || '' }}
                 </div>
             </div>
             <div class="luck-list" @scroll="handleScroll">
@@ -314,7 +314,7 @@
             <div class="header"
                 :style="{ 'backgroundImage': `url(${require('@/assets/subject/002-back-head-top.svg')})` }"
                 v-show="state.close_status == '已经过期了'">
-                <div class="close-title" v-for="item in state.close_text">{{ item }}</div>
+                <div class="close-title" v-for="item in     state.close_text">{{ item }}</div>
             </div>
 
             <!-- 没有抽中 -->
@@ -349,10 +349,11 @@
                     <img :src="require('@/assets/svg/icon-win-time.svg')" alt />
                     <span>{{ state.count_down_time || '' }}</span>
                 </div>
-                <get-more :style_type="2"
-                          :reportData="{pageSource: Report.pageSource.waitingLotteryPage,
-                                        postId: state.postId
-                                      }"></get-more>
+                <get-more :style_type="2" :reportData="{
+                    pageSource: Report.pageSource.waitingLotteryPage,
+                    postId: state.postId,
+                    redPacketType: Report.redPacketType.lottery
+                }"></get-more>
                 <div class="notification_switch" v-if="state.notification_show">
                     <span>Announcement Notification</span>
                     <a-switch v-model:checked="state.notification_switch" @change="changeNotification" />
@@ -410,8 +411,9 @@
                 </div>
             </div>
             <get-more :reportData="{
-              pageSource: Report.pageSource.missingLotteryPage,
-              postId: state.postId
+                pageSource: Report.pageSource.missingLotteryPage,
+                postId: state.postId,
+                redPacketType: Report.redPacketType.lottery
             }" v-if="state.close_status != '等待结果'"></get-more>
         </div>
 
@@ -434,7 +436,7 @@
         </div>
 
         <div v-show="state.loading_redbag" class="redbag">
-            <img :src="require('@/assets/img/icon-loading-redbag.gif')" alt />
+            <img :src="require('@/assets/img/icon-loading-redbag.png')" alt />
         </div>
 
     </div>
@@ -457,7 +459,7 @@ import FontAmount from '@/view/components/font-amount.vue'
 import FontZoom from '@/view/components/font-zoom.vue'
 import ComponentZoom from '@/view/components/component-zoom.vue'
 import GetMore from '@/view/iframe/publish/components/get-more.vue'
-import { setChromeStorage, getChromeStorage, sendChromeTabMessage } from '@/uilts/chromeExtension.js'
+import { setChromeStorage, getChromeStorage, sendCurrentTabMessage, chromeExtensionUrl } from '@/uilts/chromeExtension.js'
 import Report from "@/log-center/log"
 import { srcPublishSuccess } from '@/http/publishApi'
 import { discordAuthUrl, checkGuildJoined } from '@/http/discordApi'
@@ -603,7 +605,7 @@ async function clickLikeBtn() {
     });
 }
 function clickDone() {
-    window.open(`${chrome.runtime.getURL('/iframe/home.html')}`)
+    window.open(`${chromeExtensionUrl + ('iframe/home.html')}`)
     // 埋点
     Report.reportLog({
         objectType: Report.objectType.wallet_button,
@@ -1073,10 +1075,11 @@ const reSetBindTwtterId = (_params) => {
 const reportBindTweetSuccess = (params) => {
     let { discordTask, srcUserId } = params || {};
     discordTaskDetail = discordTask;
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
         data: {
-            screen_name: srcUserId
+            screen_name: srcUserId,
+            tweetId: state.tweetId
         }
     })
 
@@ -1639,7 +1642,7 @@ function handleRedPacket() {
 }
 
 chrome.storage.onChanged.addListener(changes => {
-    if (changes.userInfo) {
+    if (changes.userInfo && changes.userInfo.newValue) {
         // let item = JSON.parse(changes.userInfo.newValue)
         state.loading_show = false
         init()
@@ -2013,7 +2016,7 @@ function onRuntimeMsg() {
                 break;
             case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
                 let { user } = req.data || {};
-                if (user && user.result && user.result.legacy) {
+                if (req.tweetId == state.tweetId && user && user.result && user.result.legacy) {
                     let legacy = user.result.legacy;
                     reportParams.twitterFans = legacy ? legacy.followers_count : 0;
 
@@ -3385,7 +3388,7 @@ body {
 
 .none {
     display: flex;
-    align-item: center;
+    align-items: center;
     justify-content: center;
     width: 100%;
     height: 100%;

+ 26 - 20
src/view/iframe/red-packet/red-packet.vue

@@ -210,10 +210,11 @@
           </div>
         </div>
       </div>
-      <get-more  :reportData="{
-                    pageSource: Report.pageSource.received_success_page,
-                    postId: state.postId
-                  }" ></get-more>
+      <get-more :reportData="{
+        pageSource: Report.pageSource.received_success_page,
+        postId: state.postId,
+        redPacketType: Report.redPacketType.giveaway
+      }"></get-more>
     </div>
 
 
@@ -245,7 +246,7 @@
         type: PlayType.common,
         validityDuration: state.detail.validityDuration,
         userInfo: {
-          nickName: state.detail.postUserInfo.name,
+          nickName: state.detail.postUserInfo.nickName,
           avatarUrl: state.detail.postUserInfo.avatarUrl
         },
         rewardType: state.detail.rewardType,
@@ -368,9 +369,10 @@
         </div>
       </div>
       <get-more :reportData="{
-                    pageSource: Report.pageSource.expiredPage,
-                    postId: state.postId
-                  }" ></get-more>
+        pageSource: Report.pageSource.expiredPage,
+        postId: state.postId,
+        redPacketType: Report.redPacketType.giveaway
+      }"></get-more>
     </div>
 
 
@@ -392,7 +394,7 @@
     </div>
 
     <div v-show="state.loading_redbag" class="redbag">
-      <img :src="require('@/assets/img/icon-loading-redbag.gif')" alt />
+      <img :src="require('@/assets/img/icon-loading-redbag.png')" alt />
     </div>
 
   </div>
@@ -413,7 +415,7 @@ import { message } from 'ant-design-vue';
 import FontAmount from '@/view/components/font-amount.vue'
 import FontZoom from '@/view/components/font-zoom.vue'
 import GetMore from '@/view/iframe/publish/components/get-more.vue'
-import { setChromeStorage, getChromeStorage, sendChromeTabMessage } from '@/uilts/chromeExtension.js'
+import { setChromeStorage, getChromeStorage, sendCurrentTabMessage, chromeExtensionUrl } from '@/uilts/chromeExtension.js'
 import Report from "@/log-center/log"
 import { srcPublishSuccess } from '@/http/publishApi'
 import { discordAuthUrl, checkGuildJoined } from '@/http/discordApi'
@@ -552,7 +554,7 @@ async function clickLikeBtn() {
   });
 }
 function clickDone() {
-  window.open(`${chrome.runtime.getURL('/iframe/home.html')}`)
+  window.open(`${chromeExtensionUrl + ('iframe/home.html')}`)
   // 埋点
   Report.reportLog({
     objectType: Report.objectType.wallet_button,
@@ -954,10 +956,11 @@ const reSetBindTwtterId = (_params) => {
 const reportBindTweetSuccess = (params) => {
   let { discordTask, srcUserId } = params || {};
   discordTaskDetail = discordTask;
-  sendChromeTabMessage({
+  sendCurrentTabMessage({
     actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
     data: {
-      screen_name: srcUserId
+      screen_name: srcUserId,
+      tweetId: state.tweetId
     }
   })
 
@@ -1194,6 +1197,7 @@ function setFrontConfig() {
 };
 
 function init(initParams) {
+  state.loading_show = true;
   let { type } = initParams || {};
   onPageVisbile();
   onWindowMessage();
@@ -1233,6 +1237,7 @@ function init(initParams) {
       handleErrorCode(res)
     }
   }).finally(() => {
+    state.loading_show = false
     state.loading_redbag = false
   })
 }
@@ -1431,7 +1436,7 @@ function handleRedPacket() {
 }
 
 chrome.storage.onChanged.addListener(changes => {
-  if (changes.userInfo) {
+  if (changes.userInfo && changes.userInfo.newValue) {
     // let item = JSON.parse(changes.userInfo.newValue)
     state.loading_show = false
     init()
@@ -1480,11 +1485,11 @@ function handleFinishRedPacket() {
     if (res.code == 0) {
       if (res.data.finished) {
         state.receiveAmount = res.data.receiveAmount
-        if (state.receiveAmount == 0) {
-          showRabbitPage()
-        } else {
-          state.status = 'success'
-        }
+        // if (state.receiveAmount == 0) {
+        //   showRabbitPage()
+        // } else {
+        //   state.status = 'success'
+        // }
         init()
         // 埋点
         Report.reportLog({
@@ -1806,7 +1811,7 @@ function onRuntimeMsg() {
         break;
       case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
         let { user } = req.data || {};
-        if (user && user.result && user.result.legacy) {
+        if (req.tweetId == state.tweetId && user && user.result && user.result.legacy) {
           let legacy = user.result.legacy;
           reportParams.twitterFans = legacy ? legacy.followers_count : 0;
 
@@ -2074,6 +2079,7 @@ body {
     position: fixed;
     top: 0;
     left: 0;
+    user-select: none;
 
     img {
       margin-top: 172px;

+ 21 - 19
src/view/iframe/tab-group/joined-group-list.vue

@@ -1,14 +1,11 @@
 <template>
     <div class="group-list-page" ref="pageWrapperDom">
         <div class="title">
-            <img class="icon" :src="require('@/assets/svg/icon-joined-group-logo.svg')" >
+            <img class="icon" :src="require('@/assets/svg/icon-joined-group-logo.svg')">
             NFT Owners Group
         </div>
         <div class="content-wrapper">
-            <nft-group-list style="height: 100%" 
-                ref="groupListDom"
-                :showBadge="true" 
-                @clickCallBack="clickHandler"
+            <nft-group-list style="height: 100%" ref="groupListDom" :showBadge="true" @clickCallBack="clickHandler"
                 @updateList="updateList"></nft-group-list>
         </div>
     </div>
@@ -18,14 +15,16 @@
 import { onMounted, ref, nextTick } from "vue";
 import NftGroupList from '@/view/components/nft-group-list.vue';
 
-import { sendChromeTabMessage, setChromeStorage } from '@/uilts/chromeExtension.js';
+import { sendCurrentTabMessage, setChromeStorage } from '@/uilts/chromeExtension.js';
 
 let groupListDom = ref(null);
 
 const clickHandler = (params) => {
-    setChromeStorage({ groupTabData: JSON.stringify({
-        deTabVal: 'deGroupTab'
-    })})
+    setChromeStorage({
+        groupTabData: JSON.stringify({
+            deTabVal: 'deGroupTab'
+        })
+    })
     let url = `https://twitter.com/${params.defaultTwitterAccount}`;
     sendMessageToContent({
         actionType: 'IFRAME_PAGE_JUMP',
@@ -36,11 +35,11 @@ const clickHandler = (params) => {
 }
 
 const sendMessageToContent = (params) => {
-    let {actionType, data} = params || {};
+    let { actionType, data } = params || {};
     chrome.tabs.getCurrent((tab) => {
         chrome.tabs.sendMessage(tab.id, {
-        actionType,
-        data,
+            actionType,
+            data,
         }, (res) => { console.log(res) });
     })
 }
@@ -52,8 +51,8 @@ const updateList = (data) => {
 const setHeight = (data) => {
     const maxHeight = 321;
     nextTick(() => {
-        if(!data || !data.length) { 
-            sendChromeTabMessage({
+        if (!data || !data.length) {
+            sendCurrentTabMessage({
                 actionType: "IFRAME_JOINED_GROUP_SET_STYLE",
                 data: {
                     height: '0px'
@@ -62,17 +61,17 @@ const setHeight = (data) => {
             return;
         }
         let listDom = document.querySelector('.list-content');
-        if(listDom) {
+        if (listDom) {
             const titleDomHeight = 56, marginBottom = 12;
             let height = maxHeight;
             let contentHeight = listDom.offsetHeight + titleDomHeight + marginBottom;
 
-            if(contentHeight < maxHeight) {
-                height =  contentHeight;
+            if (contentHeight < maxHeight) {
+                height = contentHeight;
             } else {
                 height = maxHeight;
             }
-            sendChromeTabMessage({
+            sendCurrentTabMessage({
                 actionType: "IFRAME_JOINED_GROUP_SET_STYLE",
                 data: {
                     height: height + 'px'
@@ -87,7 +86,9 @@ onMounted(() => {
 </script>
 
 <style  lang="scss">
-html, body, #app {
+html,
+body,
+#app {
     width: 100%;
     height: 100%;
     margin: 0;
@@ -115,6 +116,7 @@ html, body, #app {
         }
 
     }
+
     .content-wrapper {
         height: calc(100% - 60px);
         overflow-y: auto;

+ 24 - 17
src/view/iframe/tool-box/buy-nft.vue

@@ -1,26 +1,22 @@
 <template>
-    <div class="nft-layer">
+    <div class="nft-layer" v-if="nftAuthINfo">
         <div class="title">
-            <img @click="close" :src=" require('@/assets/svg/icon-close.svg') " />
-            <span class="text">Unlock by Ruomeng NFT</span>
+            <img @click="close" :src="require('@/assets/svg/icon-close.svg')" />
+            <span class="text">Unlock by {{ nftAuthINfo.nftProjectName }} NFT</span>
         </div>
         <div class="content">
             <div class="img">
                 <img v-if="nftAuthINfo && nftAuthINfo.icon" :src="nftAuthINfo.icon" />
             </div>
             <div class="tips">
-                <span>only Ruomeng NFT holder can view the content</span>
+                <span>only {{ nftAuthINfo.nftProjectName }} NFT holder can view the content</span>
             </div>
-            <div
-                class="btn"
-                v-if="btnStatus"
-                @click="buy"
-                v-click-log="{
-                    pageSource: Report.pageSource.buy_posteditor_nft_dialog,
-                    objectType: Report.objectType.buy_button,
-                    nftProjectId: nftAuthINfo.certNftProjectId || '',
-                    postId: postId,
-                }">
+            <div class="btn" v-if="btnStatus" @click="buy" v-click-log="{
+                pageSource: Report.pageSource.buy_posteditor_nft_dialog,
+                objectType: Report.objectType.buy_button,
+                nftProjectId: nftAuthINfo.certNftProjectId || '',
+                postId: postId,
+            }">
                 <span>Buy NFT to Participate</span>
             </div>
             <div class="btn disabled" v-else>
@@ -36,7 +32,7 @@ import { ref, onBeforeMount } from 'vue';
 import { ElMessage } from 'element-plus';
 import { getQueryString } from '@/uilts/help';
 import { getPostEditorNftCertInfo } from '@/http/toolBoxApi';
-import { getChromeStorage, sendChromeTabMessage } from "@/uilts/chromeExtension";
+import { getChromeStorage, sendCurrentTabMessage } from "@/uilts/chromeExtension";
 import "element-plus/es/components/message/style/css";
 
 const postId = ref('')
@@ -44,7 +40,7 @@ const btnStatus = ref(false)
 const nftAuthINfo = ref(null)
 
 const close = () => {
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: 'Hide_ToolBox_By_Nft'
     })
 }
@@ -89,7 +85,7 @@ onBeforeMount(() => {
         }
     }).then(res => {
         let { code, data } = res;
-        if ( code === 0 ) {
+        if (code === 0) {
             btnStatus.value = true;
             nftAuthINfo.value = data;
             // report
@@ -110,6 +106,7 @@ body {
     margin: 0;
     padding: 0;
 }
+
 .nft-layer {
     position: absolute;
     top: 50%;
@@ -119,11 +116,13 @@ body {
     transform: translate(-50%, -50%);
     border-radius: 20px;
     background: #FFFFFF;
+
     .title {
         height: 48px;
         display: flex;
         align-items: center;
         box-shadow: 0px 0.5px 0px #D1D9DD;
+
         img {
             width: 24px;
             height: 24px;
@@ -131,24 +130,28 @@ body {
             margin-right: 12px;
             cursor: pointer;
         }
+
         .text {
             font-size: 16px;
             font-weight: 500;
             line-height: 19px;
         }
     }
+
     .content {
         .img {
             display: flex;
             height: 250px;
             align-items: center;
             justify-content: center;
+
             img {
                 width: 150px;
                 height: 150px;
                 border-radius: 5px;
             }
         }
+
         .tips {
             position: relative;
             font-size: 14px;
@@ -158,6 +161,7 @@ body {
             margin: auto;
             margin-bottom: 28px;
             width: calc(100% - 30px);
+
             &::before {
                 position: absolute;
                 top: 50%;
@@ -168,6 +172,7 @@ body {
                 height: 1px;
                 background-color: rgba($color: #000000, $alpha: .2);
             }
+
             &::after {
                 position: absolute;
                 top: 50%;
@@ -179,6 +184,7 @@ body {
                 background-color: rgba($color: #000000, $alpha: .2);
             }
         }
+
         .btn {
             display: flex;
             align-items: center;
@@ -192,6 +198,7 @@ body {
             font-weight: 600;
             border-radius: 100px;
             background: #1D9BF0;
+
             &.disabled {
                 background: #CDCDCD;
                 cursor: not-allowed;

+ 24 - 18
src/view/iframe/tool-box/card.vue

@@ -13,13 +13,14 @@
         <div class="content" v-else>
             <template v-if="state.showMask && state.status != '固定右上角'">
                 <div class="mask" @click="confirmStatus">
-                    <img class="luck" :src=" require('@/assets/svg/icon-post-lock.svg') " />
+                    <img class="luck" :src="require('@/assets/svg/icon-post-lock.svg')" />
                     <div class="btn">
-                        <img class="img" v-if="state.detail && state.detail.nftProjectIcon" :src=" state.detail.nftProjectIcon " />
-                        <div class="font">Available for holders of {{state.detail.nftProjectName}} NFT</div>
+                        <img class="img" v-if="state.detail && state.detail.nftProjectIcon"
+                            :src="state.detail.nftProjectIcon" />
+                        <div class="font">Available for holders of {{ state.detail.nftProjectName }} NFT</div>
                     </div>
                 </div>
-                <img class="mask_bg" v-if="state.detail.linkImagePath" :src=" state.detail.linkImagePath " />
+                <img class="mask_bg" v-if="state.detail.viewBgImagePath" :src="state.detail.viewBgImagePath" />
             </template>
             <iframe :src="state.iframe_url" v-show="state.status == 'iframe'" ref="dom_iframe" frameborder="0"
                 scrolling="yes" allow="camera *;microphone *"></iframe>
@@ -72,7 +73,7 @@
     </div>
 </template>
 <script setup>
-import { getChromeStorage, setChromeStorage, defineProps, sendChromeTabMessage } from "@/uilts/chromeExtension";
+import { getChromeStorage, setChromeStorage, defineProps, sendCurrentTabMessage } from "@/uilts/chromeExtension";
 import { getPostDetail } from '@/http/redPacket.js'
 import { getPostEditorNftCertInfo, unlockNftCert } from '@/http/toolBoxApi'
 import { guid, getQueryString } from "@/uilts/help";
@@ -150,7 +151,7 @@ onMounted(() => {
     state.postId = getQueryString('postId')
     state.tweetId = getQueryString('tweetId')
 
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: 'Get_ToolBox_Fixed_TweetId'
     }, (res) => {
         if (res == state.tweetId) {
@@ -195,13 +196,13 @@ const getDetail = () => {
                     postId: state.postId,
                     tweetId: state.tweetId
                 }, () => {
-                  Report.reportLog({
-                    objectType: Report.objectType.tweetPostBinded,
-                    redPacketType: 5,
-                    postId: state.postId,
-                  }, {
-                    'post-editor-url': state.detail.convertUrl
-                  });
+                    Report.reportLog({
+                        objectType: Report.objectType.tweetPostBinded,
+                        redPacketType: 5,
+                        postId: state.postId,
+                    }, {
+                        'post-editor-url': state.detail.convertUrl
+                    });
                 })
             }
             console.log('postBizData', state.detail)
@@ -253,7 +254,7 @@ const getNftInfoStatus = () => {
         }
     }).then(res => {
         let { code, data } = res;
-        if ( code === 0 ) {
+        if (code === 0) {
             nftAuthINfo.value = data;
         }
     })
@@ -303,7 +304,7 @@ const confirmStatus = () => {
             if (nftAuthINfo.value && nftAuthINfo.value?.certStatus === 1) {
                 succBack()
             } else {
-                sendChromeTabMessage({
+                sendCurrentTabMessage({
                     actionType: 'Set_ToolBox_By_Nft',
                     data: {
                         postId: state.postId,
@@ -416,7 +417,7 @@ const handleFull = () => {
             // 切换状态
             state.status = '固定右上角'
             state.show_btn = false
-            sendChromeTabMessage({
+            sendCurrentTabMessage({
                 actionType: 'Set_ToolBox_Fixed',
                 data: {
                     type: '全屏',
@@ -439,7 +440,7 @@ const handleFixed = () => {
     // 切换状态
     state.show_btn = false
     state.status = '固定右上角'
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: 'Set_ToolBox_Fixed',
         data: {
             type: '固定右上角',
@@ -659,11 +660,13 @@ const msgListener = (req, sender, sendResponse) => {
             flex-direction: column;
             width: 100%;
             height: 100%;
-            background-color: rgba($color: #000000, $alpha: .8);
+            background-color: rgba($color: #000000, $alpha: .5);
+
             .luck {
                 width: 100px;
                 height: 100px;
             }
+
             .btn {
                 display: flex;
                 align-items: center;
@@ -673,6 +676,7 @@ const msgListener = (req, sender, sendResponse) => {
                 margin-top: 12px;
                 border-radius: 100px;
                 background: #1D9BF0;
+
                 .img {
                     overflow: hidden;
                     width: 35px;
@@ -680,6 +684,7 @@ const msgListener = (req, sender, sendResponse) => {
                     margin-right: 16px;
                     border-radius: 4px;
                 }
+
                 .font {
                     width: 188px;
                     color: #fff;
@@ -690,6 +695,7 @@ const msgListener = (req, sender, sendResponse) => {
                 }
             }
         }
+
         .mask_bg {
             position: absolute;
             z-index: 1;

+ 14 - 10
src/view/iframe/tool-box/full.vue

@@ -14,13 +14,13 @@
         <div class="content">
             <template v-if="showMask">
                 <div class="mask" @click="confirmStatus">
-                    <img class="luck" :src=" require('@/assets/svg/icon-post-lock.svg') " />
+                    <img class="luck" :src="require('@/assets/svg/icon-post-lock.svg')" />
                     <div class="btn">
-                        <img class="img" v-if="detail.nftProjectIcon" :src=" detail.nftProjectIcon " />
-                        <div class="font">Available for holders of {{detail.nftProjectName}} NFT</div>
+                        <img class="img" v-if="detail.nftProjectIcon" :src="detail.nftProjectIcon" />
+                        <div class="font">Available for holders of {{ detail.nftProjectName }} NFT</div>
                     </div>
                 </div>
-                <img class="mask_bg" v-if="detail.linkImagePath" :src=" detail.linkImagePath " />
+                <img class="mask_bg" v-if="detail.viewBgImagePath" :src="detail.viewBgImagePath" />
             </template>
             <iframe :src="state.iframe_url" frameborder="0" allow="camera *;microphone *"></iframe>
         </div>
@@ -30,7 +30,7 @@
 import { reactive, ref } from "vue";
 import { ElMessage } from 'element-plus'
 import { unlockNftCert } from '@/http/toolBoxApi'
-import { getChromeStorage, sendChromeTabMessage } from "@/uilts/chromeExtension";
+import { getChromeStorage, sendCurrentTabMessage } from "@/uilts/chromeExtension";
 import "element-plus/es/components/message/style/css";
 
 let state = reactive({
@@ -81,7 +81,7 @@ const clickFull = () => {
 }
 
 const changeFull = () => {
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: 'Set_ToolBox_Fixed',
         data: {
             type: '全屏',
@@ -92,7 +92,7 @@ const changeFull = () => {
 }
 
 const changeFixed = () => {
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: 'Set_ToolBox_Fixed',
         data: {
             type: '固定右上角',
@@ -111,7 +111,7 @@ const clickClose = () => {
 }
 
 const sendClose = () => {
-    sendChromeTabMessage({
+    sendCurrentTabMessage({
         actionType: 'Set_ToolBox_Fixed',
         data: {
             type: '关闭',
@@ -140,7 +140,7 @@ const confirmStatus = () => {
             if (nftAuthINfo.value && nftAuthINfo.value?.certStatus === 1) {
                 succBack()
             } else {
-                sendChromeTabMessage({
+                sendCurrentTabMessage({
                     actionType: 'Set_ToolBox_By_Nft',
                     data: {
                         postId: postId.value,
@@ -237,11 +237,13 @@ const hideMask = (data) => {
             flex-direction: column;
             width: 100%;
             height: 100%;
-            background-color: rgba($color: #000000, $alpha: .8);
+            background-color: rgba($color: #000000, $alpha: .5);
+
             .luck {
                 width: 100px;
                 height: 100px;
             }
+
             .btn {
                 display: flex;
                 align-items: center;
@@ -252,6 +254,7 @@ const hideMask = (data) => {
                 margin-top: 12px;
                 border-radius: 100px;
                 background: #1D9BF0;
+
                 .img {
                     overflow: hidden;
                     width: 35px;
@@ -259,6 +262,7 @@ const hideMask = (data) => {
                     margin-right: 16px;
                     border-radius: 4px;
                 }
+
                 .font {
                     width: 188px;
                     color: #fff;

+ 334 - 0
src/view/iframe/treasure-hunt/all-receive-list.vue

@@ -0,0 +1,334 @@
+<template>
+    <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>
+            </div>
+            <div class="right">
+              <img @click="showOptionSheet = true" :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>
+    </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"
+
+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
+  }
+])
+
+
+let page_num = 1
+let page_size = 10
+let sortType = 2;
+let list_end = false
+
+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 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 {
+    width: 375px;
+    height: 580px;
+    position: relative;
+
+    .head {
+        width: 100%;
+        height: 48px;
+        box-sizing: border-box;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+
+        background: #FFFFFF;
+        box-shadow: inset 0px -1px 0px #F2F2F2;
+
+        .left {
+          display: flex;
+          align-items: center;
+        }
+
+        img {
+            width: 24px;
+            height: 24px;
+            margin: 0 12px;
+            cursor: pointer;
+        }
+
+        span {
+            font-style: normal;
+            font-weight: 700;
+            font-size: 17px;
+            line-height: 20px;
+            letter-spacing: 0.3px;
+
+            color: #000000;
+        }
+    }
+
+    .content {
+        position: relative;
+        height: calc(100% - 48px);
+
+        .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;
+            height: 100%;
+
+            .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;
+                    }
+
+                    .time {
+                        color: #A6A6A6;
+                        font-weight: 400;
+                        font-size: 12px;
+                        margin-right: 17px;
+                    }
+
+                    .money {
+                        color: #FCB936;
+                        font-weight: 500;
+                        font-size: 13px;
+                        margin-right: 16px;
+
+                    }
+                }
+            }
+        }
+    }
+
+    .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;
+
+        img {
+          width: 24px;
+          margin: 0 12px;
+        }
+
+        .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;
+          }
+        }
+    }
+}
+
+.loading {
+    width: 100px;
+    height: 100px;
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    margin-left: -50px;
+    margin-top: -50px;
+    animation: rotation 1s linear infinite;
+}
+
+.empty {
+    width: 100px;
+    height: 100px;
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    margin-left: -50px;
+    margin-top: -50px;
+}
+
+@keyframes rotation {
+    from {
+        -webkit-transform: rotate(0deg);
+    }
+
+    to {
+        -webkit-transform: rotate(360deg);
+    }
+}
+</style>

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

@@ -0,0 +1,336 @@
+<template>
+    <div class="area-boxs">
+        <!-- 箱子 -->
+        <div class="box-process">
+            <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">
+                </hover-tip> -->
+                <!-- 金额 -->
+                <span class="money" :style="{ 'color': item.money_color, 'top': item.money_top }">
+                    <img :src="require('@/assets/svg/icon-green-yes.svg')" alt="" v-if="item.openStatus == 1" />
+                    {{ item.openStatus == 0 ? item.txt : item.amountUsdValue }}
+                </span>
+                <!-- 宝箱 -->
+                <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)" />
+                <!-- 发光 -->
+                <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"
+                    :style="{ 'margin-left': item.flash_margin_top, 'margin-top': item.flash_margin_top, 'width': item.flash_width, 'height': item.flash_width }" />
+
+                <!-- 进度条 -->
+                <div class="line" :style="{ 'width': item.line_width, 'left': item.line_left }">
+                    <div class="full" :style="{ 'width': item.full_width }"></div>
+                </div>
+            </div>
+        </div>
+        <!-- 人数 -->
+        <div class="people">
+            <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>
+            </div>
+
+        </div>
+    </div>
+</template>
+<script setup>
+import { onMounted, inject, watch } from 'vue'
+import { checkIsLogin } from '@/uilts/chromeExtension'
+
+
+let state = inject('state')
+// ---- box 区域
+let silver_close_box = require('@/assets/img/icon-silver-close-box.png')
+let silver_open_box = require('@/assets/img/icon-silver-open-box.png')
+let gold_open_box = require('@/assets/img/icon-gold-open-box.png')
+let gold_close_box = require('@/assets/img/icon-gold-close-box.png')
+let purple_open_box = require('@/assets/img/icon-purple-open-box.png')
+let purple_close_box = require('@/assets/img/icon-purple-close-box.png')
+let global_refresh = inject('global_refresh')
+
+watch(global_refresh, () => {
+    if (global_refresh.value) {
+        init()
+    }
+})
+
+onMounted(() => {
+    init()
+})
+const init = () => {
+    boxsStatus()
+    btnStatus()
+}
+
+async function clickBox(item) {
+    let _userInfo = await checkIsLogin()
+    if (!_userInfo) {
+        return
+    }
+
+    if (item.openStatus == 0 && item.taskFinishStatus == 1 && state.btn_loading == false) {
+        state.btn_loading = true
+        state.treasureOpen()
+    }
+}
+
+state.boxs = [{
+    icon: '',
+    icon_open: silver_open_box,
+    icon_close: silver_close_box,
+    icon_margin_left: '17px',
+    icon_width: '46px',
+
+    show: false,
+    flash_width: '70px',
+    flash_margin_top: `-${70 / 2}px`,
+    line_width: '25px',
+    line_left: `-${25 - 10}px`,
+    money_color: '#BFCCE4',
+    money_top: '-20px'
+}, {
+    icon: '',
+    icon_open: gold_open_box,
+    icon_close: gold_close_box,
+
+    show: false,
+    icon_width: '46px',
+    flash_width: '70px',
+    icon_margin_left: '33px',
+    flash_margin_top: `-${70 / 2}px`,
+    line_width: '55px',
+    line_left: `-${55 - 10}px`,
+    money_color: '#FCB936', money_top: '-20px'
+
+}, {
+    icon: '',
+    icon_open: gold_open_box,
+    icon_close: gold_close_box,
+
+    show: false,
+    icon_width: '66px',
+    flash_width: '90px',
+    icon_margin_left: '31px',
+    flash_margin_top: `-${90 / 2}px`,
+    line_width: '60px',
+    line_left: `-${60 - 15}px`,
+    money_color: '#FCB936', money_top: '-15px'
+
+}, {
+    icon: purple_close_box,
+    icon_open: purple_open_box,
+    icon_close: purple_close_box,
+    show: false,
+    icon_width: '84px',
+    flash_width: '108px',
+    icon_margin_left: '23px',
+    flash_margin_top: `-${108 / 2}px`,
+    line_width: '60px',
+    line_left: `-${60 - 20}px`,
+    money_color: '#FCB936', money_top: '-10px'
+}]
+
+const setLineFull = (box_num = 0, finishNeedInviteCount = 0, successInviteCount = 0) => {
+    state.boxs[box_num].full_width = `${(successInviteCount / finishNeedInviteCount) * 100}%`
+}
+
+const btnStatus = () => {
+    for (let i in state.boxs) {
+        if (state.boxs[i].taskFinishStatus == 0) {
+            let num = state.boxs[i].finishNeedInviteCount - state.boxs[i].successInviteCount
+            if (num == 1) {
+                state.open_btn.txt = 'Invite 1 Friend to Open'
+            } else {
+                state.open_btn.txt = `Invite ${num} Friends to Open`
+            }
+            state.open_btn.disabled = true
+            break
+        }
+    }
+
+    state.treasureId = ''
+    let open_num = 0
+    // 有打开的箱子 Open the chest
+    state.boxs.forEach((item, index) => {
+        if (item.taskFinishStatus == 1 && item.openStatus == 0) {
+            state.open_btn.txt = 'Open the Treasure Chest'
+            state.open_btn.disabled = false
+            if (!state.treasureId) {
+                state.treasureId = item.id
+            }
+        }
+        setLineFull(index, item.finishNeedInviteCount, item.successInviteCount)
+        // 箱子全部打开了
+        if (item.openStatus == 1) {
+            open_num++
+        }
+        if (open_num == state.boxs.length) {
+            state.open_btn.txt = 'All Chests Have Been Opened'
+            state.open_btn.disabled = true
+        }
+    })
+}
+
+
+
+const mouseItem = (i) => {
+    state.boxs[i].show = true
+    state.active_share_channel = true
+}
+const mouseLeaveItem = (i) => {
+    state.boxs[i].show = false
+    state.active_share_channel = false
+}
+
+const boxsStatus = () => {
+    state.detail.treasureRecords.forEach((item, index) => {
+        let box = state.boxs[index]
+        if (item.openStatus == 0) {
+            box.icon = box.icon_close
+        } else {
+            box.icon = box.icon_open
+        }
+        box.txt = `$${item.targetAmountUsdValue}`
+        state.boxs[index] = Object.assign(box, item)
+    })
+}
+
+</script>
+<style lang="scss" scoped>
+.area-boxs {
+    position: relative;
+
+    .people {
+        display: flex;
+        position: absolute;
+        bottom: 0px;
+        left: 10px;
+
+        .item {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            text-align: center;
+            user-select: none;
+
+            img {
+                user-select: none;
+                width: 16px;
+                height: 16px;
+                margin-right: 3px;
+                cursor: pointer;
+            }
+
+            span {
+                color: #FFFFFF;
+                opacity: 0.4;
+                font-weight: 500;
+                font-size: 12px;
+            }
+
+
+        }
+
+    }
+
+    .box-process {
+        width: 350px;
+        height: 90px;
+        margin: 0 auto;
+        display: flex;
+        align-items: center;
+
+        img {
+            width: 60px;
+            height: 60px;
+            z-index: 2;
+            user-select: none;
+        }
+
+
+
+        .item {
+            z-index: 2;
+            display: flex;
+            justify-content: center;
+            position: relative;
+
+            .box {
+
+                cursor: pointer;
+            }
+
+            .active {
+                animation: bounce-up 0.5s linear infinite;
+            }
+
+            .flash {
+                position: absolute;
+                left: 50%;
+                top: 50%;
+                z-index: 0;
+                width: 100%;
+                height: 100%;
+            }
+
+            .money {
+                display: flex;
+                align-items: center;
+                white-space: nowrap;
+                position: absolute;
+                top: -20px;
+                font-weight: 700;
+                font-size: 16px;
+
+                img {
+                    width: 13px;
+                    height: 13px;
+                    margin-right: 4px;
+                }
+            }
+
+            .line {
+                width: 40px;
+                height: 4px;
+                background: rgba(255, 210, 59, 0.2);
+                position: absolute;
+                border-radius: 100px;
+                overflow: hidden;
+                left: -40px;
+                top: 50%;
+
+                .full {
+                    position: absolute;
+                    left: 0;
+                    top: 0;
+                    height: 4px;
+                    width: 0px;
+                    background: #FFD23B;
+                }
+            }
+        }
+    }
+}
+
+@keyframes bounce-up {
+    25% {
+        -webkit-transform: translateY(1px);
+    }
+
+    50%,
+    100% {
+        -webkit-transform: translateY(0);
+    }
+
+    75% {
+        -webkit-transform: translateY(-1px);
+    }
+}
+</style>

+ 3 - 6
src/view/iframe/treasure-hunt/components/btn.vue

@@ -47,22 +47,19 @@ let props = defineProps({
 const emit = defineEmits(['on-click'])
 
 const clickBtn = () => {
-    if (!props.disabled) {
+    if (props.disabled == false && props.loading == false) {
         emit('on-click')
     }
 }
 
+
 const refresh = () => {
     if (!refreshRotate.value) {
         refreshRotate.value = true;
         setTimeout(() => {
             refreshRotate.value = false;
         }, 1000)
-
-        state.init(() => {
-            state.inviteInit()
-            state.inviteList()
-        })
+        state.refreshInit()
     }
 }
 </script>

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

@@ -0,0 +1,191 @@
+<template>
+    <div class="area-carousel">
+        <!-- left -->
+        <div class="area-left" @click="state.page_show = '总邀请者页'">
+            <div>
+                <img :src="require('@/assets/svg/icon-user1.svg')" alt="" />
+                <span>{{ state.detail.receiveCountWithAmount }}</span>
+            </div>
+            <div>Get Money</div>
+        </div>
+        <div class="area-right">
+            <div class="area-success-message" @mouseover="mouseOver" @mouseleave="mouseLeave">
+                <div class="content-success-message" ref="content_success_message">
+                    <div class="success-message" v-for="item, index in state.success_message_list" :key="index"
+                        @click="clickItem(item)">
+                        <img :src="item.userInfo.avatarUrl" alt="" />
+                        <span>Get</span> &nbsp;
+                        <span>${{ item.amountUsdValue }}</span>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+</template>
+<script setup>
+import { inject, ref, onMounted, watch } from 'vue'
+import { receiveListV2 } from '@/http/treasure.js'
+let content_success_message = ref(null)
+let state = inject('state')
+let global_refresh = inject('global_refresh')
+// ---- 走马灯
+state.success_message_list = []
+
+watch(global_refresh, () => {
+    if (global_refresh.value) {
+        init()
+    }
+})
+
+onMounted(() => {
+    init()
+})
+
+const init = () => {
+    receiveListV2({
+        params: {
+            postId: state.postId,
+            pageNum: 1,
+            pageSize: 1000,
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            state.success_message_list = res.data
+            state.success_message_list = state.success_message_list.concat(state.success_message_list)
+
+            while (state.success_message_list.length < 10 && state.success_message_list.length > 0) {
+                state.success_message_list = state.success_message_list.concat(state.success_message_list)
+            }
+
+            if (content_success_message && content_success_message.value) {
+                let dom = content_success_message.value
+                let s = state.success_message_list.length * 4
+                dom.style.animationDuration = s + 's'
+            }
+        }
+    })
+}
+const clickItem = (item) => {
+    window.open(`https://twitter.com/${item.userInfo.nickName}`)
+}
+
+const mouseOver = () => {
+    if (content_success_message && content_success_message.value && content_success_message.value.style) {
+        content_success_message.value.style.animationPlayState = 'paused'
+    }
+}
+const mouseLeave = () => {
+    if (content_success_message && content_success_message.value && content_success_message.value.style) {
+        content_success_message.value.style.animationPlayState = 'running'
+    }
+}
+</script>
+<style lang="scss" scoped>
+.area-carousel {
+    width: 100%;
+    display: flex;
+
+    .area-left {
+        cursor: pointer;
+        user-select: none;
+        width: 78px;
+
+
+        div:nth-child(1) {
+            display: flex;
+            align-items: center;
+
+            img {
+                width: 16px;
+                height: 16px;
+                margin-left: 14px;
+                margin-right: 6px;
+            }
+
+            span {
+                color: #FFFFFF;
+                font-weight: 600;
+                font-size: 12px;
+            }
+        }
+
+        div:nth-child(2) {
+            margin: 6px 0;
+            text-align: center;
+            color: #FFFFFF;
+            opacity: 0.4;
+            font-weight: 400;
+
+        }
+
+    }
+
+    .area-right {
+        flex: 1;
+        overflow: hidden;
+
+        .area-success-message {
+            height: 30px;
+            width: 100%;
+
+            .content-success-message {
+                width: fit-content;
+                display: flex;
+                animation: rolling 18s linear infinite;
+                animation-duration: 10s;
+                animation-play-state: running;
+
+                .success-message {
+                    cursor: pointer;
+                    width: fit-content;
+                    height: 30px;
+                    padding: 0 9px;
+                    border-radius: 100px;
+                    background: rgba(255, 255, 255, 0.1);
+                    display: flex;
+                    align-items: center;
+                    overflow: hidden;
+                    margin-right: 10px;
+
+                    img {
+                        width: 20px;
+                        height: 20px;
+                        border-radius: 100px;
+                        margin-right: 5px;
+
+                    }
+
+                    span {
+                        font-style: normal;
+                        font-weight: 500;
+                        font-size: 12px;
+                        line-height: 14px;
+                        white-space: nowrap;
+                    }
+
+                    span:nth-child(2) {
+                        color: #FFFFFF;
+                        opacity: 0.5;
+
+                    }
+
+                    span:nth-child(3) {
+                        color: #FFFFFF;
+                    }
+                }
+            }
+        }
+    }
+}
+
+@keyframes rolling {
+    from {
+        transform: translateX(0);
+    }
+
+    to {
+        transform: translateX(-50%);
+    }
+}
+</style>

+ 2 - 2
src/view/iframe/treasure-hunt/components/dialog.vue

@@ -25,7 +25,7 @@ const clickBtn = () => {
 <style lang="scss" scoped>
 .content {
     width: 375px;
-    height: 500px;
+    height: 100%;
     display: flex;
     align-items: center;
     justify-content: center;
@@ -39,7 +39,7 @@ const clickBtn = () => {
         opacity: .9;
         position: fixed;
         width: 375px;
-        height: 500px;
+        height: 100%;
     }
 
     .dialog {

+ 3 - 2
src/view/iframe/treasure-hunt/components/head.vue

@@ -48,7 +48,8 @@ const clickItem = () => {
         }
 
         span {
-            color: #B69882;
+            color: #FFFFFF;
+            opacity: 0.6;
             font-weight: 400;
             margin-left: 5px;
             font-size: 11px;
@@ -65,7 +66,7 @@ const clickItem = () => {
 
         span:first-child {
             color: #FFFFFF;
-            opacity: 0.7;
+            opacity: 0.6;
         }
 
         span:last-child {

+ 262 - 96
src/view/iframe/treasure-hunt/components/invite-friends.vue

@@ -1,33 +1,60 @@
 <template>
     <div class="invite-friends">
-        <div class="txt">To open the treasure chest you need to share the URL to your friends. Make sure they finish
-            the
-            tasks.</div>
-        <div class="area-url">
-            <div class="url">{{ state.detail.inviteUrl }}</div>
-            <div class="btn copy-btn" @click="clickCopy" v-click-log="state.log_invite_copy_btn_click"
+      <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>
+        <div class="invite-friends-content-body">
+          <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 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"  />
+              <div class="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">
-                Copy
+              <img :src="require('@/assets/svg/icon-copy-url-teasure.svg')" alt="">
+              <div class="name">
+                Copy URL
+              </div>
             </div>
         </div>
-        <div class="share-list">
-            <img :src="item.iconPath" alt="" v-for="item in state.share_list" :data-clipboard-text="item.inviteContent"
-                @click="clickShare(item)" class="share-item" />
         </div>
-        <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false"
+      </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>
+        </div>
+      </div>
     </div>
 </template>
 <script setup>
 import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
 import { inviteChannel } from '@/http/treasure'
-import { inject, onMounted } from 'vue'
+import { inject, onMounted, ref } from 'vue'
 import Report from "@/log-center/log"
+import { getFrontConfig } from "@/http/account";
+import { faceShareRedirectUrl } from '@/http/configAPI'
+import { setChromeStorage } from '@/uilts/chromeExtension.js'
 
 let ClipboardJS = require('clipboard');
 
+let loadingImg = require('@/assets/img/icon-loading-channel.png');
+
+let channelLoadingImg = ref(loadingImg);
 let state = inject('state')
 
 state.log_invite_btn_show = {
@@ -37,7 +64,7 @@ state.log_invite_btn_show = {
     redPacketType: Report.redPacketType.treasure,
     shareLinkId: state.invite_code,
     myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.detail.inviteCount,
+    currentInvitedNum: state.inviteCount,
     postId: state.postId
 }
 
@@ -48,7 +75,7 @@ state.log_invite_btn_click = {
     redPacketType: Report.redPacketType.treasure,
     shareLinkId: state.invite_code,
     myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.detail.inviteCount,
+    currentInvitedNum: state.inviteCount,
     postId: state.postId
 }
 state.log_invite_copy_btn_click = {
@@ -58,17 +85,64 @@ state.log_invite_copy_btn_click = {
     redPacketType: Report.redPacketType.treasure,
     shareLinkId: state.invite_code,
     myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.detail.inviteCount,
+    currentInvitedNum: state.inviteCount,
     postId: state.postId
 }
+
+let facebookAppConfig = {
+    facebookAppId: "",
+    faceShareRedirectUrl
+};
+
+let selectShareApp = ref({});
+let showShareTips = ref(false);
+let followUserStr = ref('');
+
 onMounted(() => {
     state.btn_loading = false
+    setFrontConfig();
+    initInviteChannel();
+    getFollowUserStr();
+})
+
+const getFollowUserStr = () => {
+  let arr = [];
+  if(state.follows && state.follows.length) {
+    for(let i = 0; i < state.follows.length; i++) {
+      let item = state.follows[i];
+      arr.push('@'+item.name);
+    }
+  }
+  followUserStr.value = arr.join(" or ");
+}
+
+chrome.management.onDisabled.addListener(() => {
+    initInviteChannel()
+})
+chrome.management.onEnabled.addListener(() => {
+    initInviteChannel()
+})
+
+chrome.management.onInstalled.addListener(() => {
+    initInviteChannel()
+})
+chrome.management.onUninstalled.addListener(() => {
+    initInviteChannel()
+})
+
+let linePluginInstalled
+const initInviteChannel = () => {
     try {
         chrome.management.get('ophjlpahpchlmihnnnihgmmeilfjmjjc', (res) => {
-            let linePluginInstalled = 0
+            if ((res && linePluginInstalled == 1) || (!res && linePluginInstalled == 0)) {
+                return
+            }
             if (res) {
                 linePluginInstalled = 1
+            } else {
+                linePluginInstalled = 0
             }
+
             inviteChannel({
                 params: {
                     linePluginInstalled,
@@ -83,8 +157,7 @@ onMounted(() => {
     } catch (error) {
         console.error(error)
     }
-
-})
+}
 
 async function clickBtn() {
     let _userInfo = await state.checkIsLogin()
@@ -96,33 +169,75 @@ async function clickBtn() {
 }
 
 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)
+        // state.toast.txt = 'Copy Successfully'
+        // state.toast.has_icon = true
+        // state.toast.show = true
+        // setTimeout(() => {
+        //     state.toast.show = false
+        // }, 2000)
         e.clearSelection();
     })
-    chrome.tabs.create({
-        url: item.redirectPath
-    });
-    let strArr = item.treasureInviteUrl.split('/');
-    let channelName = window.atob(strArr[strArr.length-1]);
+    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)
+    }
     Report.reportLog({
-      businessType: Report.businessType.buttonClick,
-      pageSource: Report.pageSource.inviteFriendsPage,
-      objectType: Report.objectType.channelButton,
-      shareLinkId: state.invite_code,
-      myShareLinkId: state.detail.inviteCopyUrl,
-      currentInvitedNum: state.detail.inviteCount,
+        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': channelName
+        'channel-name': item.name
     });
 }
 
+const setFrontConfig = () => {
+    getFrontConfig({
+        params: {},
+    }).then((res) => {
+        if (res.code == 0) {
+            facebookAppConfig.facebookAppId = res.data.fbClientId;
+        }
+    });
+};
+
+
 
 const clickCopy = () => {
     var clipboard = new ClipboardJS('.copy-btn');
@@ -148,80 +263,131 @@ const clickCopy = () => {
 </script>
 <style lang="scss" scoped>
 .invite-friends {
-    padding: 18px 16px 25px 16px;
+    padding: 9px 14px 14px 14px;
     background: #fff;
+    box-sizing: border-box;
 
-    .txt {
-        font-style: normal;
-        font-weight: 500;
-        font-size: 13px;
-        line-height: 18px;
-        /* or 129% */
-        margin-bottom: 18.5px;
+    .invite-friends-content {
+      max-height: 242px;
+      overflow-y: auto;
+      margin-bottom: 10px;
+      box-sizing: border-box;
 
-        letter-spacing: 0.3px;
+      .invite-friends-content-head {
+        margin-bottom: 16px;
+        padding: 0 6px;
+        box-sizing: border-box;
 
-        color: #000000;
-    }
+        .title {
+          font-weight: 900;
+          font-size: 18px;
+          margin-bottom: 7px;
+        }
+        .info {
+          font-weight: 400;
+          font-size: 12px;
+          color: #7A7A7A;
+          line-height: 15px;
+        }
+
+      }
 
-    .area-url {
-        height: 70px;
-        background: rgba(29, 155, 240, 0.01);
-        border: 1px solid #1D9BF0;
-        border-radius: 5px;
-        display: flex;
-        align-items: center;
-        padding-left: 15px;
-        padding-right: 11px;
-        justify-content: space-between;
-
-        .url {
-            display: -webkit-box;
-            -webkit-box-orient: vertical;
-            -webkit-line-clamp: 3;
-            overflow: hidden;
-            width: 194px;
-
-            color: #737373;
-            font-weight: 400;
-            font-size: 13px;
-            white-space: normal;
-
-            word-wrap: break-word;
-
-            word-break: break-all;
+      .invite-friends-content-body {
+        position: relative;
+
+        .tips {
+          position: absolute;
+          top: -42px;
+          left: 0;
+          width: 146px;
+        }
+
+        .share-list-active {
+          background: rgba(29, 155, 240, 0.1);
+          border: 1.5px solid #1D9BF0 !important;
+          border-radius: 10px;
         }
+        .share-list {
+          display: flex;
+          flex-wrap: wrap;
+          width: 100%;
+          box-sizing: border-box;
+          border: 1.5px solid #fff;
 
-        .btn {
+          .share-item {
             user-select: none;
-            background: #1D9BF0;
-            border-radius: 35px;
-            width: 100px;
-            text-align: center;
-            line-height: 37px;
-            height: 37px;
-            font-weight: 700;
-            font-size: 15px;
-            color: #fff;
+            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;
+            }
+          }
+
+          .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;
 
-    .share-list {
-        margin-top: 20px;
+      .content {
         text-align: center;
-        margin-bottom: 14px;
+      }
 
-        img {
-            user-select: none;
-            cursor: pointer;
-            width: 33px;
-            height: 33px;
-            margin-right: 14px;
-            border-radius: 100px;
-        }
-    }
+      .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;
+    }
 
+    to {
+      background: #E3E3E4;
+    }
+  }
 }
 </style>

+ 86 - 0
src/view/iframe/treasure-hunt/components/invite-layer.vue

@@ -0,0 +1,86 @@
+<template>
+    <div class="layer down">
+        <div v-if="Number(state.start_task.amountValue) > 0">
+            <div class="n1">
+                You Win <span>${{ state.start_task.usdAmountValue }} !</span>
+            </div>
+            <div class="n2">Invite Friends to Open the Chest!</div>
+        </div>
+        <div v-else>
+            <div class="n1">
+                You are not <span>Real New follower</span>
+            </div>
+            <div class="n2">Invite Friends to Open the Chest!</div>
+        </div>
+    </div>
+</template>
+<script setup>
+import { inject } from 'vue'
+let state = inject('state')
+
+</script>
+<style scoped lang="scss">
+.layer {
+    background: #005A98;
+    opacity: 0.9;
+    width: 100%;
+    height: 83px;
+    text-align: center;
+    z-index: 19;
+    position: fixed;
+    top: -83px;
+    color: #fff;
+
+
+
+
+
+    .n1 {
+        margin-top: 20px;
+        text-align: center;
+        font-weight: 800;
+        font-size: 18px;
+
+
+        span {
+            color: #FCB936;
+        }
+    }
+
+    .n2 {
+        margin-top: 10px;
+        font-weight: 800;
+        font-size: 14px;
+    }
+}
+
+.down {
+    animation-name: frame_down, frame_up;
+    animation-duration: 0.5s, 0.5s;
+    animation-timing-function: ease, ease;
+    animation-delay: 0s, 5s;
+    animation-iteration-count: 1, 1;
+    animation-fill-mode: forwards, forwards;
+}
+
+@keyframes frame_down {
+    0% {
+        top: -83px;
+    }
+
+    100% {
+        top: 0px
+    }
+}
+
+@keyframes frame_up {
+    0% {
+        top: 0px
+    }
+
+    100% {
+        top: -83px;
+
+    }
+}
+</style>

+ 390 - 159
src/view/iframe/treasure-hunt/components/invite-list.vue

@@ -1,214 +1,445 @@
 <template>
-    <div class="content" v-show-log="state.log_invite_list_show">
-        <div class="error" v-if="state.invited_list.length == 0">
-            Invite people to hunt treasure with you!
+  <div class="content">
+    <div class="horizontal-invited-wrapper" v-if="state.invited_list.length">
+      invited({{ state.inviteCount }})
+      <div class="horizontal-invited-list" v-show-log="state.log_invite_list_show " @mouseleave="invitedListMouseleave($event)">
+        <template v-for="(item, index) in state.invited_list" :key="index">
+          <div class="invited-item" v-if="index < 5" @mouseenter="invitedItemMouseenter(item)">
+            <img :src="item.userInfo.avatarUrl" />
+          </div>
+        </template>
+      </div>
+      <img class="more" v-if="state.invited_list.length > 5" :src="require('@/assets/svg/icon-invited-more.svg')"
+        @mouseenter="moreMouseenter" @mouseleave="moreMouseleave" />
+    </div>
+
+    <div class="invited-user-info" @mouseenter="invitedItemMouseenter()" @mouseleave="invitedListMouseleave($event)"
+      v-if="hoverInvitedUserInfo.userInfo">
+      <div class="left">
+        <img class="avatar" @click="clickItem(hoverInvitedUserInfo)" :src="hoverInvitedUserInfo.userInfo.avatarUrl" />
+      </div>
+      <div class="right">
+        <div class="user-info">
+          <div class="name" @click="clickItem(hoverInvitedUserInfo)">
+            @{{ hoverInvitedUserInfo.userInfo.nickName }}
+          </div>
+          <div class="time">
+            {{ getTime(hoverInvitedUserInfo.timestamp) }}
+          </div>
         </div>
-        <div class="list" v-else @scroll="handleScroll($event)">
-            <div class="item" v-for="item in state.invited_list">
-                <div class="left">
-                    <img :src="item.userInfo.avatarUrl" alt="" @click="clickItem(item)" />
-                </div>
-                <div class="right">
-                    <div>{{ item.userInfo.nickName }}</div>
-                    <div>{{ getTime(item.timestamp) }}</div>
-                </div>
-            </div>
+        <span class="channel" v-if="hoverInvitedUserInfo.channelName">
+          <img class="app-icon" :src="hoverInvitedUserInfo.channelIcon" />
+          {{hoverInvitedUserInfo.channelName}}
+        </span>
+      </div>
+    </div>
+
+    <div class="vertical-invited-wrapper" v-if="showVerticalInvitedList" @mouseenter="moreMouseenter"
+      @mouseleave="moreMouseleave" @scroll="handleScroll($event)">
+      <div class="invited-user-info" v-for="(item, index) in state.invited_list" :key="index">
+        <div class="left">
+          <img @click="clickItem(item)" class="avatar" :src="item.userInfo.avatarUrl" />
         </div>
-        <div class="footer">
-            <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false" :loading="state.btn_loading"
-                :disabled="state.open_btn.disabled" v-click-log="state.log_invite_btn_click" @onClick="clickBtn"
-                font-weight="600"></v-btn>
+        <div class="right">
+          <div class="user-info">
+            <div class="name" @click="clickItem(item)">
+              @{{ item.userInfo.nickName }}
+            </div>
+            <div class="time">
+              {{ getTime(item.timestamp) }}
+            </div>
+          </div>
+          <span class="channel" v-if="item.channelName">
+            <img class="app-icon" :src="item.channelIcon" />
+            {{item.channelName}}
+          </span>
         </div>
+      </div>
     </div>
+  </div>
 </template>
 <script setup>
-import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
-import { inviteList } from '@/http/treasure'
-import { inject, onMounted } from 'vue'
+import { inviteList, inviteListRefresh } from '@/http/treasure'
+import { inject, onMounted, ref, watch } from 'vue'
 import Report from "@/log-center/log"
 
 var moment = require('moment')
 let state = inject('state')
+let global_refresh = inject('global_refresh')
+
 state.invited_list = []
-let page_num = 1
-let page_size = 10
+
+let page_num = 1;
+let page_size = 200
+let listLoadMore = false
 let list_end = false
 
-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.detail.inviteCount,
-    postId: state.postId
-}
+let hoverInvitedUserInfo = ref({});
+let showVerticalInvitedList = ref(false);
+let timer = null;
+let timer1 = null;
 
 state.log_invite_list_show = {
-    businessType: Report.businessType.pageView,
-    pageSource: Report.pageSource.beenInvitedPage,
-    redPacketType: Report.redPacketType.treasure,
-    shareLinkId: state.invite_code,
-    myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.detail.inviteCount,
-    postId: state.postId
+  businessType: Report.businessType.pageView,
+  pageSource: Report.pageSource.beenInvitedPage,
+  redPacketType: Report.redPacketType.treasure,
+  shareLinkId: state.invite_code,
+  myShareLinkId: state.detail.inviteCopyUrl,
+  currentInvitedNum: state.inviteCount,
+  postId: state.postId
 }
 
+watch(global_refresh, () => {
+    if (global_refresh.value) {
+      list()
+    }
+})
+
 onMounted(() => {
-    state.btn_loading = false
-    list()
+  state.btn_loading = false;
+  list()
 })
 
+const invitedItemMouseenter = (params) => {
+  if (timer) clearTimeout(timer)
+  if (params) {
+    hoverInvitedUserInfo.value = params;
+  }
+}
+
+const invitedListMouseleave = (params) => {
+  timer = setTimeout(function () {
+    hoverInvitedUserInfo.value = {};
+  }, 600);
+}
+
+const moreMouseenter = () => {
+  if (timer1) clearTimeout(timer1)
+  showVerticalInvitedList.value = true;
+}
+
+const moreMouseleave = () => {
+  timer1 = setTimeout(function () {
+    showVerticalInvitedList.value = false;
+  }, 600);
+}
+
 const clickItem = (item) => {
-    window.open(`https://twitter.com/${item.userInfo.nickName}`)
+  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) {
-        list_end = true
-        if (state.invited_list.length == page_num * page_size) {
-            page_num++
-        }
-        list()
-    }
+  if (list_end) {
+    return
+  }
+  e = e.target
+  if ((e.clientHeight + e.scrollTop) / e.scrollHeight > .8) {
+    list_end = true
+    inviteListScroll()
+  }
 }
 
 const list = () => {
-    state.inviteList()
+  state.inviteListRefresh()
 }
 
-state.inviteList = () => {
-    inviteList({
-        params: {
-            inviteCode: state.invite_code,
-            postId: state.postId,
-            pageNum: page_num,
-            pageSize: page_size,
-        }
+// 刷新时调用
+state.inviteListRefresh = () => {
+  let last_timestamp = 0
+  if (state.invited_list.length > 0) {
+    last_timestamp = state.invited_list[0].timestamp
+  }
 
-    }).then((res) => {
-        if (res.code == 0) {
-            if (res.data.length > 0) {
-                res.data.forEach(item => {
-                    if (state.invited_list.filter((item2) => { return item2.userInfo.uid == item.userInfo.uid }).length == 0) {
-                        state.invited_list.push(item)
-                    }
-                })
-                list_end = false
-            } else {
-                list_end = false
-            }
-        }
+  inviteListRefresh({
+    params: {
+      postId: state.postId,
+      lastTimestamp: last_timestamp,
+    }
+  }).then((res) => {
+    if (res.code == 0) {
+      handleCommon(res.data)
+    }
+  })
+}
+
+const handleCommon = (data) => {
+  state.inviteCount = data.inviteCount
+   if (data.inviteUsers.length > 0) {
+    data.inviteUsers.forEach(item => {
+      if (state.invited_list.filter((item2) => { return item2.userInfo.uid == item.userInfo.uid }).length == 0) {
+        state.invited_list.push(item)
+      }
     })
+    state.invited_list = state.invited_list.sort((a, b) => {
+      return b.timestamp - a.timestamp
+    })
+
+    list_end = false
+  } else {
+    list_end = false
+  }
 }
 
-const getTime = (timestamp) => {
-    let _d1 = moment(new Date().getTime())
-    let _d2 = moment(timestamp)
-    const plural = (n, s) => {
-        let _str = `${n} ${s} ago`
-        if (n > 1) {
-            _str = `${n} ${s}s ago`
-        }
-        return _str
-    }
-    let _d = moment.duration(_d1.diff(_d2)).days()
-    if (_d) {
-        return plural(_d, 'day')
+// 滚动
+let inviteListScroll = () => {
+  let last_timestamp = 0
+  let len = state.invited_list.length
+  if (len > 0) {
+    last_timestamp = state.invited_list[len - 1].timestamp
+  }
+
+  inviteList({
+    params: {
+      inviteCode: state.invite_code,
+      postId: state.postId,
+      lastTimestamp: last_timestamp,
+      pageSize: page_size
     }
-    let _h = moment.duration(_d1.diff(_d2)).hours()
-    if (_h) {
-        return plural(_h, 'hour')
+  }).then((res) => {
+    if (res.code == 0) {
+
+      handleCommon(res.data)
     }
-    let _m = moment.duration(_d1.diff(_d2)).minutes()
-    if (_m) {
-        return plural(_m, 'min')
+  })
+}
+
+const getTime = (timestamp) => {
+  let _d1 = moment(new Date().getTime())
+  let _d2 = moment(timestamp)
+  const plural = (n, s) => {
+    let _str = `${n} ${s} ago`
+    if (n > 1) {
+      _str = `${n} ${s}s ago`
     }
-    let _s = moment.duration(_d1.diff(_d2)).seconds()
-    return plural(_s, 'sec')
+    return _str
+  }
+  let _d = moment.duration(_d1.diff(_d2)).days()
+  if (_d) {
+    return plural(_d, 'day')
+  }
+  let _h = moment.duration(_d1.diff(_d2)).hours()
+  if (_h) {
+    return plural(_h, 'hour')
+  }
+  let _m = moment.duration(_d1.diff(_d2)).minutes()
+  if (_m) {
+    return plural(_m, 'min')
+  }
+  let _s = moment.duration(_d1.diff(_d2)).seconds()
+  return plural(_s, 'sec')
 }
 
 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()
 }
 
 </script>
 <style lang="scss" scoped>
 .content {
-    position: relative;
-    height: 292px;
+  position: absolute;
+  bottom: 0px;
+  width: 100%;
+
+  .horizontal-invited-wrapper {
+    width: 100%;
+    padding: 12px 14px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    font-weight: 400;
+    font-size: 12px;
+    color: #A7A39F;
+
+    .horizontal-invited-list {
+      display: flex;
+      align-items: center;
+      cursor: pointer;
+
+      .invited-item {
+        width: 16px;
+        height: 16px;
+        padding: 0 5px;
+
+        img {
+          width: 16px;
+          height: 16px;
+          border-radius: 50%;
+        }
+      }
+    }
 
-    .footer {
-        background: #fff;
-        padding: 10px 16px 25px 16px;
+    .more {
+      margin-left: 5px;
+      cursor: pointer;
     }
+  }
 
-    .error {
-        height: 204px;
-        color: #BABABA;
-        background-color: #fff;
-        font-weight: 500;
-        font-size: 15px;
-        line-height: 204px;
-        text-align: center;
+  .vertical-invited-wrapper {
+    width: 343px;
+    height: 308px;
+    background: #FFFFFF;
+    box-shadow: 0px 4px 14px rgba(0, 0, 0, 0.25);
+    border-radius: 16px;
+    overflow-y: scroll;
+    position: absolute;
+    bottom: -316px;
+    left: 16px;
+    z-index: 1000;
+    animation: fade-in 0.25s linear forwards;
+    background: #fff;
+
+    .invited-user-info {
+      position: static !important;
+      border-radius: 0px !important;
+      box-shadow: none !important;
+      padding: 0 !important;
+      animation: none !important;
+
+      .left,
+      .right {
+        padding: 9px 0;
+      }
+
+      .left {
+        padding-left: 16px;
+      }
+
+      .right {
+        padding-right: 16px;
+        box-shadow: inset 0px -1px 0px #F2F2F2;
+        box-sizing: border-box;
+      }
+    }
+  }
+
+  .invited-user-info {
+    width: 343px;
+    padding: 9px 16px;
+    box-sizing: border-box;
+    background: #FFFFFF;
+    box-shadow: 0px 4px 14px rgba(0, 0, 0, 0.25);
+    border-radius: 16px;
+    position: absolute;
+    bottom: -62px;
+    left: 16px;
+    display: flex;
+    justify-content: space-between;
+    animation: fade-in 0.25s linear forwards;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .avatar {
+        width: 30px;
+        height: 30px;
+        margin-right: 16px;
+        border-radius: 50%;
+        cursor: pointer;
+      }
+    }
+
+    .right {
+      display: flex;
+      justify-content: space-between;
+      width: 100%;
+
+      .user-info {
+        .name {
+          margin-bottom: 5px;
+          font-weight: 500;
+          font-size: 15px;
+          cursor: pointer;
+        }
 
+        .time {
+          font-weight: 400;
+          font-size: 12px;
+          color: #A9A9A9;
+        }
+      }
+
+      .channel {
+        height: min-content;
+        display: flex;
+        align-items: center;
+        font-weight: 400;
+        font-size: 12px;
+        color: #A9A9A9;
+
+        .app-icon {
+          width: 14px;
+          height: 14px;
+          margin-right: 4px;
+          border-radius: 50%;
+        }
+      }
     }
+  }
+
+
+
+  .list {
+    background: #fff;
+    height: 204px;
+    overflow-y: auto;
+
+    .item {
+      height: 60px;
+      display: flex;
+      align-items: center;
+
+      .left {
+        width: 58px;
+        text-align: center;
 
-    .list {
-        background: #fff;
-        height: 204px;
-        overflow-y: auto;
-
-        .item {
-            height: 60px;
-            display: flex;
-            align-items: center;
-
-            .left {
-                width: 58px;
-                text-align: center;
-
-                img {
-                    border-radius: 50px;
-                    width: 30px;
-                    height: 30px;
-                }
-            }
-
-            .right {
-                flex: 1;
-                border-bottom: 1px solid #D9D9D9;
-                display: flex;
-                align-items: center;
-                height: 100%;
-                justify-content: space-between;
-
-                div:nth-child(1) {
-                    color: #000000;
-                    font-weight: 500;
-                    font-size: 15px;
-
-                }
-
-                div:nth-child(2) {
-                    color: #A6A6A6;
-                    font-weight: 400;
-                    font-size: 12px;
-                    margin-right: 17px;
-
-                }
-            }
+        img {
+          cursor: pointer;
+          border-radius: 50px;
+          width: 30px;
+          height: 30px;
         }
+      }
+
+      .right {
+        flex: 1;
+        border-bottom: 1px solid #D9D9D9;
+        display: flex;
+        align-items: center;
+        height: 100%;
+        justify-content: space-between;
+
+        div:nth-child(1) {
+          color: #000000;
+          font-weight: 500;
+          font-size: 15px;
+          cursor: pointer;
+        }
+
+        div:nth-child(2) {
+          color: #A6A6A6;
+          font-weight: 400;
+          font-size: 12px;
+          margin-right: 17px;
+
+        }
+      }
+    }
+  }
+
+  @keyframes fade-in {
+    from {
+      opacity: 0;
+    }
+
+    to {
+      opacity: 1;
     }
+  }
 }
 </style>

+ 3 - 3
src/view/iframe/treasure-hunt/components/open-box.vue

@@ -50,7 +50,7 @@ const clickBtn = () => {
     .content {
         z-index: 2;
         width: 375px;
-        height: 500px;
+        height: 580px;
         text-align: center;
         position: relative;
 
@@ -62,7 +62,7 @@ const clickBtn = () => {
         }
 
         img {
-            margin-top: 15px;
+            margin-top: 75px;
             width: 250px;
             height: 250px;
             animation: show 0.5s;
@@ -70,7 +70,7 @@ const clickBtn = () => {
 
         .mark {
             position: absolute;
-            top: 246px;
+            top: 300px;
             width: 375px;
 
             p {

+ 243 - 63
src/view/iframe/treasure-hunt/cover.vue

@@ -42,8 +42,10 @@
             <img :src="require('@/assets/svg/icon-three-line.svg')" alt="" />
             <span>to Hunt Treasure</span>
         </div>
-        <v-btn :txt="state.open_btn.txt" :font-size="'17px'" :icon="true" :disabled="false" @onClick="clickBtn"
-            :loading="state.btn_loading"></v-btn>
+        <div class="footer">
+            <v-btn :txt="state.open_btn.txt" :font-size="'17px'" :icon="true" :disabled="false" @onClick="clickBtn"
+                :loading="state.btn_loading"></v-btn>
+        </div>
     </div>
 
 </template>
@@ -55,11 +57,12 @@ import ComponentZoom from "@/view/components/component-zoom.vue";
 import { pageUrl } from "@/http/configAPI.js"
 import Report from "@/log-center/log"
 import { prepareStart, treasureStart } from '@/http/treasure.js'
-import { getChromeCookie, removeChromeCookie, getChromeStorage, sendChromeTabMessage } from '@/uilts/chromeExtension.js'
+import { getChromeCookie, removeChromeCookie, getChromeStorage, sendCurrentTabMessage } from '@/uilts/chromeExtension.js'
 import { reSetBindRepost } from '@/http/help.js'
+import { guid } from '@/uilts/help.js'
 
 let state = inject('state')
-
+let global_userInfo
 state.log_show = {
     businessType: Report.businessType.pageView,
     pageSource: Report.pageSource.pending_page,
@@ -69,24 +72,40 @@ state.log_show = {
 }
 
 chrome.storage.onChanged.addListener(changes => {
-    if (changes.userInfo) {
+    if (changes.userInfo && changes.userInfo.newValue) {
         // let item = JSON.parse(changes.userInfo.newValue)
         state.btn_loading = false
         state.init()
     }
 })
-
+let to_start_time = new Date().getTime()
+let now_time
 const toStart = (req) => {
+    now_time = new Date().getTime()
+    if (now_time - to_start_time <= 1000) {
+        return
+    }
+    to_start_time = now_time
+    console.log('to_start_time', to_start_time)
     treasureStart({
         params: {
             postId: state.postId || '',
-            inviteCode: state.invite_code || ''
+            inviteCode: state.invite_code || '',
+            frontFollowRelJSON: JSON.stringify(state.usersFollowStatusList),
+            time: new Date().getTime(),
+            guid: guid(),
+            channelCode: state.invite_channel
         }
     }).then((res) => {
+        state.usersFollowStatusList = [];
         if (res.code == 0) {
-            state.page = '开奖页'
+            // state.page = '开奖页'
+            state.init(() => {
+                state.page = '邀请页'
+                state.page_status = '显示开奖'
+                state.btn_loading = false
+            })
             state.start_task = res.data
-            state.btn_loading = false
             if (req.response) {
                 let repost_tweetId = req.response.data.data.create_tweet.tweet_results.result.rest_id
                 reSetBindRepost({
@@ -106,52 +125,190 @@ const toStart = (req) => {
 chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     switch (req.actionType) {
         case 'DO_TASK':
-            if (!req.task_type || state.tweetId != req.tweet_Id) {
+            if (!req.task_type || state.tweetId != req.tweet_Id || state.iframeId != req.iframeId) {
                 return
             }
-            if (!req.task_done && req.task_type == 'createTweet') {
+            console.log('DO_TASK', req)
+            if (req.task_type == 'createTweet1' && req.task_done == '否') {
+                console.log('createTweet1', req)
                 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 if (req.task_type == 'createTweet' && req.task_done) {
+            } else if (req.task_type == 'createTweet1' && req.task_done == '是') {
+                console.log('createTweet2', req)
                 toStart(req);
                 getChromeStorage('userInfo', (_userInfo) => {
-                    if(_userInfo) {
-                      sendChromeTabMessage({
-                        actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
-                        data: {
-                            screen_name: _userInfo.nickName,
-                            tweetId: state.tweetId,
-                            objectType: Report.objectType.repostSuccess
-                        }
-                      })
+                    if (_userInfo) {
+                        sendCurrentTabMessage({
+                            actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
+                            data: {
+                                screen_name: _userInfo.nickName,
+                                tweetId: state.tweetId,
+                                objectType: Report.objectType.repostSuccess,
+                                iframeId: state.iframeId
+                            }
+                        })
                     }
                 })
             }
             break
         case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
-                let twitterFans = 0;
-                let { user } = req.data || {};
-                if (user && user.result && user.result.legacy) {
-                    let legacy = user.result.legacy;
-                    twitterFans = legacy ? legacy.followers_count : 0;
+            if (state.iframeId != req.iframeId) {
+                return;
+            }
+            let twitterFans = 0;
+            let { user } = req.data || {};
+            if (user && user.result && user.result.legacy) {
+                let legacy = user.result.legacy;
+                twitterFans = legacy ? legacy.followers_count : 0;
+            }
+            if (state.tweetId == req.tweetId && req.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_GET_TWEET_USER_FOLLOW_STATUS_RES':
+            if (state.tweetId == req.tweetId && state.iframeId == req.iframeId) {
+
+                if (req.type == 'pre_repost') {
+                    // 发送埋点
+                    let list = getFollowStatus(req.data)
+                    log_pre_repost.names.forEach(item => {
+                        list.forEach((item2) => {
+                            if (item.name == item2.name) {
+                                if (item.type == 'invite') {
+                                    log_pre_repost.params.isFatherTwitterFans = item2.followed
+                                }
+                                if (item.type == 'post') {
+                                    log_pre_repost.params.isRootTwitterFans = item2.followed
+                                }
+                            }
+                        })
+                    })
+
+                    // 上报埋点
+                    Report.reportLog(Object.assign({
+                        objectType: Report.objectType.preRepost,
+                    }, log_pre_repost.params))
+
+                } else {
+                    state.usersFollowStatusList = getFollowStatus(req.data);
+                    // 上报埋点
+                    logPreRepost()
+                    // 做任务
+
+                    // 一键三连
+                    sendCurrentTabMessage({
+                        actionType: "IFRAME_TWITTER_API_DO_TASK",
+                        task_data: {
+                            tweet_Id: state.tweetId,
+                            tweet_text: state.rePostTweetContent
+                        },
+                        task_type: 'tasks',
+                        tasks: state.tasks,
+                        iframeId: state.iframeId
+                    })
+
+                    // double like
+                    sendCurrentTabMessage({
+                        actionType: "IFRAME_TWITTER_API_DO_TASK", task_data: {
+                            tweet_Id: state.detail.srcContentId
+                        }, task_type: 'like',
+                        iframeId: state.iframeId
+                    })
                 }
-                if (state.tweetId == req.tweetId && req.objectType == Report.objectType.repostSuccess) {
-                  Report.reportLog({
-                      objectType: Report.objectType.repostSuccess,
-                      twitterFans: twitterFans,
-                      redPacketType: Report.redPacketType.treasure,
-                      postId: state.postId,
-                      shareLinkId: state.invite_code,
-                  });
-                };
+            }
             break;
     }
 })
 
+const getFollowStatus = (arr = []) => {
+    let list = [];
+    let userInfoList = arr;
+    for (let i = 0; i < userInfoList.length; i++) {
+        let item = userInfoList[i];
+        if (item.user && item.user.result && item.user.result.legacy) {
+            let legacy = item.user.result.legacy;
+            list.push({
+                name: legacy.screen_name,
+                followed: legacy.following
+            })
+        }
+    }
+    return list
+}
+
+let log_pre_repost = {
+    params: {},
+    names: []
+}
+const logPreRepost = () => {
+    log_pre_repost.params = {}
+    log_pre_repost.names = []
+
+    // rootTwitterName  上报原始发布者的name
+    // fatherTwitterName 上报分享者的name or 原始发布者的name
+    // isFatherTwitterFans 在原始链接或分享链接 邀请者非自己
+    // isRootTwitterFans 在原始链接或分享链接 发布者非自己
+
+    let params = {}
+    params.postId = state.postId
+    if (state.page_type == '邀请链接') {
+        params.shareLinkId = state.invite_code
+        params.fatherTwitterName = state.detail.inviteUserInfo.nickName
+    } else if (state.page_type == '原始链接') {
+        params.fatherTwitterName = state.detail.postUserInfo.nickName
+    }
+    params.rootTwitterName = state.detail.postUserInfo.nickName
+    let names = []
+    if (state.detail.inviteUserInfo) {
+        if (state.detail.inviteUserInfo.uid != global_userInfo.uid) {
+            // isFatherTwitterFans = inviteUserInfo.nickName 的关注关系
+            // 发送事件校验关注关系
+            names.push({
+                type: 'invite',
+                name: state.detail.inviteUserInfo.nickName
+            })
+        }
+    } else {
+        if (state.detail.postUserInfo.uid != global_userInfo.uid) {
+            names.push({
+                type: 'invite',
+                name: state.detail.postUserInfo.nickName
+            })
+        }
+    }
+
+    if (state.detail.postUserInfo && (state.detail.postUserInfo.uid != global_userInfo.uid)) {
+        // isRootTwitterFans = postUserInfo.nickName 的关注关系
+        // 发送事件校验关注关系
+        names.push({
+            type: 'post',
+            name: state.detail.postUserInfo.nickName
+        })
+    }
+
+    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
+}
+
 const toLast = (num, bit) => {
     let str = 1
     for (let i = 0; i < bit; i++) {
@@ -161,23 +318,26 @@ const toLast = (num, bit) => {
     return Math.floor(Number(num) * _num) / _num
 }
 
-
 async function clickBtn() {
-    let _userInfo = await state.checkIsLogin()
-    if (!_userInfo) {
+    global_userInfo = await state.checkIsLogin()
+    if (!global_userInfo || !global_userInfo.uid) {
         return
     }
     if (state.cover_status == '奖励已被领光') {
         Report.reportLog({
-            pageSource: Report.pageSource.pending_page,
+            pageSource: Report.pageSource.expiredPage,
             businessType: Report.businessType.buttonClick,
             objectType: Report.objectType.getMoreGiveaway,
-            postId: state.postId
+            postId: state.postId,
+            shareLinkId: state.invite_code,
+            currentInvitedNum: state.inviteCount,
+            redPacketType: Report.redPacketType.treasure
         });
+
         window.open('https://twitter.com/search?q=%23denet');
         return
     }
-
+    state.btn_loading = true
 
     Report.reportLog({
         businessType: Report.businessType.buttonClick,
@@ -188,7 +348,6 @@ async function clickBtn() {
         postId: state.postId
     });
 
-    state.btn_loading = true
     setTimeout(() => {
         if (state.btn_loading == true) {
             state.btn_loading = false
@@ -202,6 +361,7 @@ async function clickBtn() {
     }, (res) => {
         if (res && res.inviteCode) {
             state.invite_code = res.inviteCode
+            state.invite_channel = res.channel ? window.atob(res.channel) : '';
         }
         startBtn()
     })
@@ -221,29 +381,35 @@ const startBtn = () => {
                 url: pageUrl,
             })
 
-            let text = res.data.rePostTweetContent
-            // 一键三连
-            chrome.tabs.getCurrent((tab) => {
-                chrome.tabs.sendMessage(tab.id, {
-                    actionType: "IFRAME_TWITTER_API_DO_TASK",
-                    task_data: {
-                        tweet_Id: state.tweetId,
-                        tweet_text: text
-                    },
-                    task_type: 'tasks',
-                    tasks: state.tasks,
-                });
-            })
+            state.rePostTweetContent = res.data.rePostTweetContent;
+            getUsersFollowStatus();
         } else {
             state.init()
         }
     })
 }
+
+const getUsersFollowStatus = () => {
+    let userList = state.follows;
+
+    if (userList && userList.length) {
+        sendCurrentTabMessage({
+            actionType: "IFRAME_API_GET_TWEET_USER_FOLLOW_STATUS",
+            data: {
+                userList: userList,
+                tweetId: state.tweetId,
+            },
+            iframeId: state.iframeId
+        })
+    }
+}
+
 </script>
 <style lang="scss" scoped>
 .cover {
+    position: relative;
     width: 375px;
-    height: 500px;
+    height: 580px;
     background: linear-gradient(179.96deg, #25180D 38.82%, #5E4025 55.4%, #876635 61.6%, #24180C 71.59%);
     border-radius: 20px;
 
@@ -268,7 +434,7 @@ const startBtn = () => {
     }
 
     .waring {
-        margin-top: 54px;
+        margin-top: 94px;
         font-weight: 900;
         font-size: 34px;
         color: #FFFFFF;
@@ -283,12 +449,12 @@ const startBtn = () => {
 
     .in-invite {
         height: 28px;
-        margin-top: 20px;
+        margin-top: 30px;
         margin-bottom: 10px;
     }
 
     .invite {
-        background: rgba(255, 255, 255, 0.1);
+        /* background: rgba(255, 255, 255, 0.1); */
         height: 28px;
         display: flex;
         align-items: center;
@@ -309,7 +475,8 @@ const startBtn = () => {
         }
 
         span {
-            color: #BE9F89;
+            color: #FFFFFF;
+            opacity: 0.6;
         }
     }
 
@@ -385,12 +552,15 @@ const startBtn = () => {
             line-height: 15px;
             color: #FFFFFF;
 
-            opacity: 0.7;
+            opacity: 0.6;
         }
     }
 
     .box {
         text-align: center;
+        position: absolute;
+        width: 100%;
+        bottom: 155px;
 
         img {
             width: 160px;
@@ -400,11 +570,16 @@ const startBtn = () => {
     }
 
     .mark {
+        position: absolute;
+        bottom: 84px;
         display: flex;
         align-items: center;
         justify-content: center;
-        margin-top: 24px;
-        margin-bottom: 15px;
+        width: 100%;
+
+        img {
+            margin-right: 9px;
+        }
 
         span {
             font-weight: 500;
@@ -415,5 +590,10 @@ const startBtn = () => {
         }
     }
 
+    .footer {
+        width: 100%;
+        position: absolute;
+        bottom: 16px;
+    }
 }
 </style>

+ 103 - 24
src/view/iframe/treasure-hunt/index.vue

@@ -2,27 +2,35 @@
     <v-cover v-if="state.page == '封面页'"></v-cover>
     <v-invite v-if="state.page == '邀请页'"></v-invite>
     <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>
+    <div v-show="state.loading_redbag" class="redbag">
+        <img :src="require('@/assets/img/icon-loading-redbag.png')" alt />
+    </div>
+
 </template>
 <script setup>
-import { reactive, provide, onMounted } from 'vue'
+import { reactive, provide, onMounted, ref } from 'vue'
 import VCover from '@/view/iframe/treasure-hunt/cover.vue'
 import VInvite from '@/view/iframe/treasure-hunt/invite.vue'
 import VResult from '@/view/iframe/treasure-hunt/result.vue'
 import { inviteDetail, treasureDetail, treasureOpen } from '@/http/treasure.js'
-import { reSetBindTwtterId, reSetBindRepost } from '@/http/help.js'
+import { reSetBindTwtterId, reSetBindPostContent, reSetBindRepost } from '@/http/help.js'
 import { getQueryString } from '@/uilts/help'
-import { getChromeStorage, sendChromeTabMessage } from '@/uilts/chromeExtension.js'
+import { getChromeStorage, sendCurrentTabMessage } from '@/uilts/chromeExtension.js'
 import VToast from '@/view/iframe/treasure-hunt/components/toast.vue'
 import OpenBox from '@/view/iframe/treasure-hunt/components/open-box.vue'
 import Report from "@/log-center/log"
 
 let state = reactive({
+    loading_redbag: true,
     page: '',
+    page_status: '',
     detail: {},
     oldDetail: {},
     btn_loading: false,
+    timer: null,
     open_box: {
         showed: false,
         show: false,
@@ -37,16 +45,22 @@ let state = reactive({
         show: false,
     },
     start_task: {},
-    toast: {}
+    toast: {},
+    iframeId: ''
 })
+let global_refresh = ref(false)
+provide('global_refresh', global_refresh)
 provide('state', state)
 
 let params = {}
 onMounted(() => {
     params = JSON.parse(getQueryString('params') || '{}')
+    state.iframeId = getQueryString('iframeId') || ''
     state.postId = params.post_Id || ''
     state.tweetId = params.tweet_Id || ''
     state.invite_code = params.invite_code || ''
+    state.page_type = params.page_type || ''
+
     state.init();
     onRuntimeMsg();
 })
@@ -77,7 +91,7 @@ state.init = (callback) => {
             }
         }).then((res) => {
             if (res.code == 0) {
-
+                state.loading_redbag = false
                 handleCommon(res, callback)
                 // 绑定repostSrcContentId
                 if (!res.data.repostSrcContentId) {
@@ -97,7 +111,17 @@ state.init = (callback) => {
             }
         }).then((res) => {
             if (res.code == 0) {
+                state.loading_redbag = false
                 handleCommon(res, callback)
+                // 原始链接绑定post content
+                if (!res.data.postSrcContent) {
+                    sendCurrentTabMessage({
+                        actionType: "GET_CONTENT_BY_TWITTER_ID",
+                        data: {
+                            tweet_Id: state.tweetId
+                        }
+                    })
+                }
             }
         })
     }
@@ -111,7 +135,7 @@ const reportOpenBoxLog = () => {
             redPacketType: Report.redPacketType.treasure,
             shareLinkId: state.invite_code,
             myShareLinkId: state.detail.inviteCopyUrl,
-            currentInvitedNum: state.detail.inviteCount,
+            currentInvitedNum: state.inviteCount,
             postId: state.postId
         });
         state.open_box.showed = false
@@ -124,7 +148,7 @@ const reportOpenBoxLog = () => {
             redPacketType: Report.redPacketType.treasure,
             shareLinkId: state.invite_code,
             myShareLinkId: state.detail.inviteCopyUrl,
-            currentInvitedNum: state.detail.inviteCount,
+            currentInvitedNum: state.inviteCount,
             postId: state.postId
         });
         state.open_box.clicked = false
@@ -150,20 +174,32 @@ const handleCommon = (res, callback) => {
             postId: state.postId || '',
             tweetId: state.tweetId || ''
         }, () => {
-            sendChromeTabMessage({
+            sendCurrentTabMessage({
                 actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
                 data: {
                     screen_name: state.detail.postUserInfo.nickName,
                     tweetId: state.tweetId,
-                    objectType: Report.objectType.tweetPostBinded
+                    objectType: Report.objectType.tweetPostBinded,
+                    iframeId: state.iframeId
                 }
             })
+            state.init()
         })
     }
     handleStatus(callback)
 }
 let silver_open_box_big = require('@/assets/img/icon-silver-open-box-big.png')
 let gold_open_box_big = require('@/assets/img/icon-gold-open-box-big.png')
+let purple_open_box_big = require('@/assets/img/icon-purple-open-big.png')
+
+state.refreshInit = () => {
+    state.init(() => {
+        global_refresh.value = true
+        setTimeout(() => {
+            global_refresh.value = false
+        }, 1000)
+    })
+}
 
 state.treasureOpen = () => {
     treasureOpen({
@@ -177,10 +213,12 @@ state.treasureOpen = () => {
             // icon
             for (let i in state.boxs) {
                 if (state.boxs[i].id == state.treasureId) {
-                    if (i > 0) {
-                        state.open_box.icon = gold_open_box_big
-                    } else {
+                    if (i == 0) {
                         state.open_box.icon = silver_open_box_big
+                    } else if (i == 1 || i == 2) {
+                        state.open_box.icon = gold_open_box_big
+                    } else if (i == 3) {
+                        state.open_box.icon = purple_open_box_big
                     }
                     break
                 }
@@ -189,10 +227,7 @@ state.treasureOpen = () => {
             state.open_box.showed = true
             state.open_box.data = res.data
 
-            state.init(() => {
-                state.inviteInit()
-                state.inviteList()
-            })
+            state.refreshInit()
         } else {
             switch (String(res.code)) {
                 case '2037':
@@ -216,10 +251,7 @@ state.treasureOpen = () => {
                 state.toast.show = false
             }, 2000)
 
-            state.init(() => {
-                state.inviteInit()
-                state.inviteList()
-            })
+            state.refreshInit()
         }
     }).catch(() => {
         state.btn_loading = false
@@ -238,12 +270,11 @@ const handleStatus = (callback) => {
     //  显示结束页面
 
     let { status, joinStatus } = state.detail || {}
-    state.open_btn.txt = 'Start'
     // 如果 夺宝状态 = 未开始
     if (status == 0) {
-        state.page = '封面页'
-
+        // 未做处理
     }
+
     // 如果 夺宝状态 = 进行中
     else if (status == 1) {
         // 如果 夺宝参与状态 = 未参与夺宝
@@ -257,7 +288,9 @@ const handleStatus = (callback) => {
         }
         // 如果 夺宝参与状态 = 已参与夺宝
         else if (joinStatus == 1) {
-            state.page = '邀请页'
+            if (state.page_show != '总邀请者页') {
+                state.page = '邀请页'
+            }
         }
     }
     // 如果 夺宝状态 = 已结束
@@ -266,6 +299,15 @@ const handleStatus = (callback) => {
         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
+        });
         return
     }
     callback && callback()
@@ -274,7 +316,19 @@ const handleStatus = (callback) => {
 function onRuntimeMsg() {
     chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
         switch (req.actionType) {
+            case 'CONTENT_GET_TWEET_TXT':
+                if (req.data.tweet_Id == state.tweetId && !state.detail.postSrcContent) {
+                    state.detail.postSrcContent = req.data.txt
+                    reSetBindPostContent({
+                        postId: state.postId || '',
+                        postSrcContent: req.data.txt,
+                    })
+                }
+                break
             case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
+                if (state.iframeId != req.iframeId) {
+                    return;
+                }
                 let twitterFans = 0;
                 let { user } = req.data || {};
                 if (user && user.result && user.result.legacy) {
@@ -300,5 +354,30 @@ html,
 body {
     margin: 0;
     padding: 0;
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+
+    .redbag {
+        z-index: 222;
+        text-align: center;
+        width: 375px;
+        height: 580px;
+        position: fixed;
+        top: 0;
+        left: 0;
+        user-select: none;
+
+        img {
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            margin-top: -65px;
+            margin-left: -65px;
+            width: 130px;
+            height: 130px;
+        }
+    }
+
 }
 </style>

+ 30 - 353
src/view/iframe/treasure-hunt/invite.vue

@@ -1,58 +1,40 @@
 <template>
-    <!-- 邀请页 -->
-    <div class="area-process" v-show-log="state.log_invite_show">
-        <v-head :left-data="state.detail.postUserInfo || null" :rightData="state.detail.remainAmountUsdValue"></v-head>
-        <div class="box-process">
-            <div class="item" v-for="item, i in state.boxs">
-                <hover-tip :txt="item.txt" v-show="item.show || item.openStatus" :icon="item.hover_icon"></hover-tip>
-                <img :src="item.icon" alt="" @mouseenter="mouseItem(i)" @mouseleave="mouseLeaveItem(i)" />
-                <img :src="require('@/assets/img/icon-flash-active.png')" alt="" class="flash"
-                    v-if="item.openStatus == 0 && item.taskFinishStatus == 1" />
-            </div>
-            <div class="line">
-                <div class="full" ref="line_full"></div>
-            </div>
-        </div>
-        <div class="area-success-message" @mouseover="mouseOver" @mouseleave="mouseLeave">
-            <div class="content-success-message" ref="content_success_message">
-                <div class="success-message" v-for="item, index in state.success_message_list" :key="index"
-                    @click="clickItem(item)">
-                    <img :src="item.userInfo.avatarUrl" alt="" />
-                    <span>{{ item.userInfo.nickName }} </span> &nbsp;
-                    <span>Opened Treasure Chest</span>
-                </div>
+    <invite-layer v-if="state.page_status == '显示开奖'"></invite-layer>
+    <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="area1">
+                <v-head :left-data="state.detail.postUserInfo || null" :rightData="state.detail.remainAmountUsdValue">
+                </v-head>
+                <v-carousel></v-carousel>
             </div>
+            <v-boxs style="margin-top: 40px;"></v-boxs>
+            <invite-list></invite-list>
         </div>
-    </div>
 
-    <div class="area-nav">
-        <div class="item" :class="{ active: state.tab_index == i }" @click="state.tab_index = i"
-            v-for="item, i in state.tabs">
-            <img :src="require('@/assets/svg/icon-invite.svg')" alt=""
-                :style="{ opacity: state.tab_index == 0 ? '1' : '0.55' }" v-if="i == 0" />
-            <img :src="require('@/assets/svg/icon-invite-list.svg')" alt=""
-                :style="{ opacity: state.tab_index == 1 ? '1' : '0.55' }" v-if="i == 1" />
-            {{ item.txt }}
+        <div class="area-info">
+            <invite-friends></invite-friends>
+            <!-- -->
         </div>
     </div>
-    <div class="area-info">
-        <invite-friends v-show="state.tab_index == 0"></invite-friends>
-        <invite-list v-show="state.tab_index == 1"></invite-list>
-    </div>
     <v-dialog v-show="state.dialog.show"></v-dialog>
 </template>
 <script setup>
 import { ref, onMounted, watch, inject } from 'vue'
-import { receiveList } from '@/http/treasure.js'
+import AllReceiveList from '@/view/iframe/treasure-hunt/all-receive-list.vue'
 import VHead from '@/view/iframe/treasure-hunt/components/head.vue'
 import InviteList from '@/view/iframe/treasure-hunt/components/invite-list.vue'
 import HoverTip from '@/view/iframe/treasure-hunt/components/hover-tip.vue'
 import InviteFriends from '@/view/iframe/treasure-hunt/components/invite-friends.vue'
 import VDialog from '@/view/iframe/treasure-hunt/components/dialog.vue'
+import VBoxs from '@/view/iframe/treasure-hunt/components/boxs.vue'
+import VCarousel from '@/view/iframe/treasure-hunt/components/carousel.vue'
+import InviteLayer from '@/view/iframe/treasure-hunt/components/invite-layer.vue'
 
 import Report from "@/log-center/log"
 
-let content_success_message = ref(null)
+
 let state = inject('state')
 
 state.log_invite_show = {
@@ -61,19 +43,10 @@ state.log_invite_show = {
     redPacketType: Report.redPacketType.treasure,
     shareLinkId: state.invite_code,
     myShareLinkId: state.detail.inviteCopyUrl,
-    currentInvitedNum: state.detail.inviteCount,
+    currentInvitedNum: state.inviteCount,
     postId: state.postId
 }
 
-// ---- 走马灯
-state.success_message_list = []
-
-// ---- box 区域
-let silver_close_box = require('@/assets/img/icon-silver-close-box.png')
-let silver_open_box = require('@/assets/img/icon-silver-open-box.png')
-let gold_open_box = require('@/assets/img/icon-gold-open-box.png')
-let gold_close_box = require('@/assets/img/icon-gold-close-box.png')
-
 
 // ---- tab区域 ----
 state.tab_index = 0
@@ -83,330 +56,34 @@ state.tabs = [{
     txt: 'Invited'
 }]
 
-state.boxs = []
-
-let line_full = ref(null)
 onMounted(() => {
-    state.inviteInit()
-    setInterval(() => {
-        state.init(() => {
-            state.inviteInit()
-            state.inviteList()
-        })
+    if (state.timer) {
+        return
+    }
+    state.timer = setInterval(() => {
+        state.refreshInit()
     }, 30000)
 })
 
-const clickItem = (item) => {
-    window.open(`https://twitter.com/${item.userInfo.nickName}`)
-}
-state.inviteInit = () => {
-    if (state.detail.inviteCount > 0) {
-        state.tabs[1].txt = `invited(${state.detail.inviteCount})`
-    }
-    state.boxs = []
-    state.detail.treasureRecords.forEach((item, index) => {
-        if (item.openStatus == 0) {
-            item.hover_icon = require('@/assets/svg/icon-user.svg')
-            if (index > 0) {
-                item.icon = gold_close_box
-            } else {
-                item.icon = silver_close_box
-            }
-            item.txt = item.inviteProgress
-        } else {
-            item.icon = silver_open_box
-            item.hover_icon = require('@/assets/svg/icon-green-yes.svg')
-            // 最后一条
-            if (index > 0) {
-                item.icon = gold_open_box
-            } else {
-                item.icon = silver_open_box
-            }
-            item.txt = '$' + item.amountValue
-        }
-
-        state.boxs.push(item)
-    })
-
-    receiveList({
-        params: {
-            postId: state.postId,
-            pageNum: 1,
-            pageSize: 100,
-        }
-    }).then((res) => {
-        if (res.code == 0) {
-            state.success_message_list = res.data
-            state.success_message_list = state.success_message_list.concat(state.success_message_list)
-            state.success_message_list = state.success_message_list.concat(state.success_message_list)
-
-            if (content_success_message && content_success_message.value) {
-                let dom = content_success_message.value
-                let s = state.success_message_list.length * 4
-                dom.style.animationDuration = s + 's'
-            }
-        }
-    })
-    btnStatus()
-
-}
-let line_width = 0
-const setLineFull = (box_num = 0, finishNeedInviteCount = 0, successInviteCount = 0) => {
-    if (box_num == 0) {
-        // 第一个宝箱起点是0,终点是55
-        line_width = (successInviteCount / finishNeedInviteCount) * 55
-    } else if (box_num == 1) {
-        if (line_width == 55) {
-            // 第二个宝箱起点是92,终点是155
-            line_width = 92
-            line_width = (successInviteCount / finishNeedInviteCount) * (155 - line_width) + line_width
-        }
-    } else if (box_num == 2) {
-        if (line_width == 155) {
-            line_width = 192
-            // 第二个宝箱起点是192,终点是260
-            line_width = (successInviteCount / finishNeedInviteCount) * (260 - line_width) + line_width
-        }
-    }
-    line_full.value.style.width = line_width + 'px'
-}
-
-const btnStatus = () => {
-    for (let i in state.boxs) {
-        if (state.boxs[i].taskFinishStatus == 0) {
-            let num = state.boxs[i].finishNeedInviteCount - state.boxs[i].successInviteCount
-            if (num == 1) {
-                state.open_btn.txt = 'Invite 1 Friend to Open'
-            } else {
-                state.open_btn.txt = `Invite ${num} Friends to Open`
-            }
-            state.open_btn.disabled = true
-            break
-        }
-    }
-
-    state.treasureId = ''
-    let open_num = 0
-    // 有打开的箱子 Open the chest
-    state.boxs.forEach((item, index) => {
-        if (item.taskFinishStatus == 1 && item.openStatus == 0) {
-            state.open_btn.txt = 'Open the Treasure Chest'
-            state.open_btn.disabled = false
-            if (!state.treasureId) {
-                state.treasureId = item.id
-            }
-        }
-        setLineFull(index, item.finishNeedInviteCount, item.successInviteCount)
-        // 三个箱子全部打开了
-        if (item.openStatus == 1) {
-            open_num++
-        }
-        if (open_num == state.boxs.length) {
-            state.open_btn.txt = 'All Chests Have Been Opened'
-            state.open_btn.disabled = true
-        }
-    })
-}
-
-const mouseItem = (i) => {
-    state.boxs[i].show = true
-}
-const mouseLeaveItem = (i) => {
-    state.boxs[i].show = false
-}
 
-const mouseOver = () => {
-    if (content_success_message && content_success_message.value && content_success_message.value.style) {
-        content_success_message.value.style.animationPlayState = 'paused'
-    }
-}
-const mouseLeave = () => {
-    if (content_success_message && content_success_message.value && content_success_message.value.style) {
-        content_success_message.value.style.animationPlayState = 'running'
-    }
-}
 
 </script>
 <style lang="scss"  scoped>
 .area-process {
     width: 375px;
-    height: 170px;
-    background: linear-gradient(179.96deg, #735931 0.04%, #0E0803 53.64%);
+    height: 260px;
+    background: linear-gradient(179.96deg, #25180D 48.1%, #6A4C1F 62.7%, #24180C 77.69%);
     position: relative;
 
-    .box-process {
-        width: 350px;
-        height: 90px;
-        margin: 0 auto;
-        display: flex;
-        align-items: center;
-        position: absolute;
-        top: 32px;
-        left: 13px;
-
-        img {
-            width: 60px;
-            height: 60px;
-            z-index: 2;
-        }
-
-        .item {
-            z-index: 2;
-            display: flex;
-            justify-content: center;
-            position: relative;
-
-            .flash {
-                position: absolute;
-                top: 0;
-                left: 0;
-                z-index: 0;
-                width: 100%;
-                height: 100%;
-            }
-        }
-
-        .item:nth-child(1) {
-
-            margin-left: 56px;
-        }
-
-        .item:nth-child(2) {
-            width: 60px;
-            height: 60px;
-            margin-left: 40px;
-        }
-
-        .item:nth-child(3) {
-            img {
-                width: 90px;
-                height: 90px;
-            }
-
-            margin-left: 40px;
-        }
-
-        .line {
-            width: 300px;
-            height: 4px;
-            background: rgba(255, 210, 59, 0.2);
-            position: absolute;
-            border-radius: 100px;
-            overflow: hidden;
-            left: 13px;
-            top: 45px;
-
-            .full {
-                position: absolute;
-                left: 0;
-                top: 0;
-                height: 4px;
-                width: 0px;
-                background: #FFD23B;
-            }
-        }
-
+    .area1 {
+        background: rgba(255, 255, 255, 0.1);
     }
 
-    .area-success-message {
-        height: 30px;
-        width: 100%;
-        position: absolute;
-        bottom: 13px;
-        overflow: hidden;
-
-        .content-success-message {
-            width: fit-content;
-            display: flex;
-            animation: rolling 18s linear infinite;
-            animation-duration: 10s;
-            animation-play-state: running;
-
-            .success-message {
-                cursor: pointer;
-                width: fit-content;
-                height: 30px;
-                padding: 0 9px;
-                border-radius: 100px;
-                background: rgba(255, 255, 255, 0.1);
-                display: flex;
-                align-items: center;
-                overflow: hidden;
-                margin-right: 15px;
-
-                img {
-                    width: 20px;
-                    height: 20px;
-                    border-radius: 100px;
-                    margin-right: 8px;
+    .area2 {}
 
-                }
-
-                span {
-                    font-style: normal;
-                    font-weight: 500;
-                    font-size: 12px;
-                    line-height: 14px;
-                    white-space: nowrap;
-                }
-
-                span:nth-child(2) {
-                    color: #1D9BF0;
-                }
-
-                span:nth-child(3) {
-                    color: #A8A8A8;
-                }
-            }
-        }
-    }
-}
-
-@keyframes rolling {
-    from {
-        transform: translateX(0);
-    }
-
-    to {
-        transform: translateX(-50%);
-    }
-}
-
-.area-nav {
-    width: 375px;
-    height: 38px;
-    display: flex;
-
-    .item {
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        user-select: none;
-        color: #757575;
-        background: #F0F0F0;
-        text-align: center;
-        width: 50%;
-        font-weight: 500;
-        font-size: 14px;
-        line-height: 38px;
-        cursor: pointer;
-
-        img {
-            margin-right: 8px;
-            width: 20px;
-            height: 20px;
-        }
-    }
-
-    .active {
-        background: #FFFFFF;
-        color: #000000;
-    }
 }
 
 .area-info {
     width: 375px;
-
-
 }
 </style>

+ 178 - 187
src/view/popup/currency-detail.vue

@@ -1,34 +1,27 @@
 <template>
   <div class="currency-detail-page">
-    <v-head :title="currencyInfo.tokenSymbol" 
-            :show_more="false"
-            :show_refresh="true"
-            :show_list="true"
-            :transactionsRouterParams="{
-              backUrl: 'back'
-            }"
-            back_url="/"
-            @on-refresh="onRefresh" />
+    <v-head :title="currencyInfo.tokenSymbol" :show_more="false" :show_refresh="true" :show_list="true"
+      :transactionsRouterParams="{
+        backUrl: 'back'
+      }" back_url="/" @on-refresh="onRefresh" />
     <div class="top">
-      <img
-        class="icon-currency"
-        :src="currencyInfo.iconPath"/>
+      <img class="icon-currency" :src="currencyInfo.iconPath" />
       <div class="amount">
         <div class="balance"
-            :class="{'direction-column': (currencyInfo.totalBalance.length + currencyInfo.tokenSymbol.length) > 15}">
+          :class="{ 'direction-column': (currencyInfo.totalBalance.length + currencyInfo.tokenSymbol.length) > 15 }">
           <a-tooltip :title="currencyInfo.totalBalance">
-              {{ getBit(currencyInfo.totalBalance) }}
-          </a-tooltip> 
+            {{ getBit(currencyInfo.totalBalance) }}
+          </a-tooltip>
           <template v-if="currencyInfo.totalBalance.length + currencyInfo.tokenSymbol.length < 16">
             &nbsp;&nbsp;
           </template>
           <span class="symbol">
-            {{currencyInfo.tokenSymbol}}
+            {{ currencyInfo.tokenSymbol }}
           </span>
         </div>
         <div class="final">
-          <a-tooltip :title="'$'+currencyInfo.totalUsdEstimateBalance">
-              ${{ getBit(currencyInfo.totalUsdEstimateBalance) }}
+          <a-tooltip :title="'$' + currencyInfo.totalUsdEstimateBalance">
+            ${{ getBit(currencyInfo.totalUsdEstimateBalance) }}
           </a-tooltip>
         </div>
       </div>
@@ -36,7 +29,7 @@
     <div class="bottom">
       <template v-if="showSendBtn">
         <div class="btn send-btn" v-if="enableRecharge == 1" @click="showSendGiveawayDialog(currencyInfo)">
-          <img :src="require('@/assets/svg/icon-send-giveaway.svg')" /> 
+          <img :src="require('@/assets/svg/icon-send-giveaway.svg')" />
           Send Giveaway
         </div>
         <div class="btn-wrapper">
@@ -51,23 +44,15 @@
     </div>
 
     <template v-if="showCurrencySelect">
-        <div class="selectDiv">
-            <currency-select 
-                ref="currencySelectDom"
-                :list="currenciesData"
-                @selectCurrency="selectCurrency">
-            </currency-select>
-        </div>
-        <div class="selectBg" @click="showCurrencySelect = false"></div>
+      <div class="selectDiv">
+        <currency-select ref="currencySelectDom" :list="currenciesData" @selectCurrency="selectCurrency">
+        </currency-select>
+      </div>
+      <div class="selectBg" @click="showCurrencySelect = false"></div>
     </template>
-    <input-action-sheet 
-      :visible="showDepositInput"
-      title="Enter the USD amount to be deposited"
-      :desc="depositDesc"
-      position="absolute"
-      @onInput="onDepositAmountInput"
-      @cancel="cancelDeposit"
-      @confirm="confirmDeposit"></input-action-sheet>
+    <input-action-sheet :visible="showDepositInput" title="Enter the USD amount to be deposited" :desc="depositDesc"
+      position="absolute" @onInput="onDepositAmountInput" @cancel="cancelDeposit" @confirm="confirmDeposit">
+    </input-action-sheet>
   </div>
 </template>
 
@@ -78,7 +63,7 @@ import Report from "@/log-center/log";
 import { getStorage } from "@/uilts/help";
 
 import { getCurrencyInfoBySymbol, syncChainTokenRechargeRecord } from "@/http/publishApi";
-import {setChromeStorage} from "@/uilts/chromeExtension"
+import { setChromeStorage, chromeExtensionUrl } from "@/uilts/chromeExtension"
 
 import VHead from '@/view/popup/components/head.vue'
 import currencySelect from "@/view/components/currency-select.vue";
@@ -109,42 +94,42 @@ let finalAmountData = ref({});
 
 
 const selectCurrency = (params) => {
-    showCurrencySelect.value = false;
-    let {enableRecharge, enableWithdraw} = params;
+  showCurrencySelect.value = false;
+  let { enableRecharge, enableWithdraw } = params;
 
-    if(currencyOpertionType == 'WITHDRAW') {
-      if(enableWithdraw != 1) {
-        return;
-      }
-      withdrawHandle(params);
-    } else if(currencyOpertionType == 'DEPOSIT') {
-      if(enableRecharge != 1) {
-        return;
-      }
-      depositHandle(params);
-    } else if(currencyOpertionType == 'SEND') {
-      if(enableRecharge != 1) {
-        return;
-      }
-      showSendGiveawayDialog(params);
+  if (currencyOpertionType == 'WITHDRAW') {
+    if (enableWithdraw != 1) {
+      return;
     }
+    withdrawHandle(params);
+  } else if (currencyOpertionType == 'DEPOSIT') {
+    if (enableRecharge != 1) {
+      return;
+    }
+    depositHandle(params);
+  } else if (currencyOpertionType == 'SEND') {
+    if (enableRecharge != 1) {
+      return;
+    }
+    showSendGiveawayDialog(params);
+  }
 }
 
 let withdraw_info = inject('withdraw_info')
 // 点击提现
 const clickWithdraw = () => {
-    Report.reportLog({
-        pageSource: Report.pageSource.denetHomePage,
-        businessType: Report.businessType.buttonClick,
-        objectType: Report.objectType.withdrawButton
-    });
+  Report.reportLog({
+    pageSource: Report.pageSource.denetHomePage,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.withdrawButton
+  });
 
-    if(currenciesData.value.length > 1) {
-      showCurrencySelect.value = true;
-      currencyOpertionType = "WITHDRAW";
-    } else if(currenciesData.value.length == 1){
-      withdrawHandle(currenciesData.value[0]);
-    }
+  if (currenciesData.value.length > 1) {
+    showCurrencySelect.value = true;
+    currencyOpertionType = "WITHDRAW";
+  } else if (currenciesData.value.length == 1) {
+    withdrawHandle(currenciesData.value[0]);
+  }
 }
 
 const withdrawHandle = (_params) => {
@@ -159,12 +144,12 @@ const withdrawHandle = (_params) => {
   withdraw_info.icon_net = require('@/assets/svg/icon-BNB.svg')
 
   if (_params.currencyCode == 'USD') {
-      withdraw_info.currency_code = _params.currencyCode
-      withdraw_info.paypal.amount_value = _params.balance
-      router.push('/withdraw/paypal')
+    withdraw_info.currency_code = _params.currencyCode
+    withdraw_info.paypal.amount_value = _params.balance
+    router.push('/withdraw/paypal')
   } else {
-      console.log(withdraw_info.chainInfo.iconPath)
-      router.push('/withdraw/info')
+    console.log(withdraw_info.chainInfo.iconPath)
+    router.push('/withdraw/info')
   }
 }
 
@@ -173,45 +158,45 @@ const withdrawHandle = (_params) => {
 let top_up_info = inject('top_up_info');
 
 const clickDeposit = () => {
-    Report.reportLog({
-        pageSource: Report.pageSource.denetHomePage,
-        businessType: Report.businessType.buttonClick,
-        objectType: Report.objectType.topupButton
-    });
+  Report.reportLog({
+    pageSource: Report.pageSource.denetHomePage,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.topupButton
+  });
 
-    if(currenciesData.value.length > 1) {
-      showCurrencySelect.value = true;
-      currencyOpertionType = "DEPOSIT";
-    } else if(currenciesData.value.length == 1){
-      let currencyInfo = currenciesData.value[0];
-      if(currencyInfo.currencyCode == 'USD') {
-        // 法币充值
-        showDepositInput.value = true;
-        setDepositDesc();
-          
-      } else {
-        depositHandle(currencyInfo);
-      }
+  if (currenciesData.value.length > 1) {
+    showCurrencySelect.value = true;
+    currencyOpertionType = "DEPOSIT";
+  } else if (currenciesData.value.length == 1) {
+    let currencyInfo = currenciesData.value[0];
+    if (currencyInfo.currencyCode == 'USD') {
+      // 法币充值
+      showDepositInput.value = true;
+      setDepositDesc();
+
+    } else {
+      depositHandle(currencyInfo);
     }
+  }
 }
 
 const setDepositDesc = async () => {
   let res = await payCalcFee({
-      params: {
-          amountValue: 0,
-          currencyCode: currencyInfo.value.currencyCode,
-          payChannel: 'ach',
-      },
+    params: {
+      amountValue: 0,
+      currencyCode: currencyInfo.value.currencyCode,
+      payChannel: 'ach',
+    },
   });
-  if(res.code == 0) {
-    let {feeDesc} = res.data;
+  if (res.code == 0) {
+    let { feeDesc } = res.data;
     depositDesc.value = `${feeDesc}`;
   }
 }
 
 const depositHandle = (_params) => {
   top_up_info.token = _params.currencyName || ''
-  top_up_info.token_chain = _params.tokenChain 
+  top_up_info.token_chain = _params.tokenChain
   top_up_info.token_symbol = _params.tokenSymbol || ''
   top_up_info.currency_code = _params.currencyCode
   top_up_info.icon_token = _params.iconPath || ''
@@ -219,21 +204,21 @@ const depositHandle = (_params) => {
   top_up_info.chainInfo = {
     ..._params.chainInfo
   };
-  
+
   router.push('/top-up/info');
 };
 
 
 const asyncTokenRechRecord = (currencyCode = '', cb) => {
-    syncChainTokenRechargeRecord({
-        params: {
-            currencyCode: currencyCode
-        }
-    }).then(res => {
-      cb && cb(res.data)
-    }).catch((err) => {
-      cb && cb()
-    })
+  syncChainTokenRechargeRecord({
+    params: {
+      currencyCode: currencyCode
+    }
+  }).then(res => {
+    cb && cb(res.data)
+  }).catch((err) => {
+    cb && cb()
+  })
 }
 
 const onRefresh = () => {
@@ -243,11 +228,11 @@ const onRefresh = () => {
         symbol: currencyInfo.value.tokenSymbol
       }
     }).then(res => {
-      if(res.code == 0) {
-        if(res.data && res.data.currencyCategories && res.data.currencyCategories.length) {
+      if (res.code == 0) {
+        if (res.data && res.data.currencyCategories && res.data.currencyCategories.length) {
           let data = res.data.currencyCategories[0].data;
-          if(data.length) {
-            let {totalBalance = '', totalUsdEstimateBalance = ''} = data[0] || {};
+          if (data.length) {
+            let { totalBalance = '', totalUsdEstimateBalance = '' } = data[0] || {};
             currencyInfo.value.totalBalance = totalBalance;
             currencyInfo.value.totalUsdEstimateBalance = totalUsdEstimateBalance;
           }
@@ -258,23 +243,23 @@ const onRefresh = () => {
 };
 
 const showSendGiveawayDialog = (params = {}) => {
-  if(currenciesData.value.length > 1 && currencyOpertionType != 'SEND') {
-      showCurrencySelect.value = true;
-      currencyOpertionType = "SEND";
+  if (currenciesData.value.length > 1 && currencyOpertionType != 'SEND') {
+    showCurrencySelect.value = true;
+    currencyOpertionType = "SEND";
   } else {
-      setLocalSelectCurrencyInfo(params)
-      setTimeout(() => {
-        chrome.runtime.sendMessage({ 
-          actionType: "POPUP_SHOW_DENET_PUBLISH_DIALOG", 
-          data: { } 
+    setLocalSelectCurrencyInfo(params)
+    setTimeout(() => {
+      chrome.runtime.sendMessage({
+        actionType: "POPUP_SHOW_DENET_PUBLISH_DIALOG",
+        data: {}
       });
-      }, 600)
-      currencyOpertionType = '';
+    }, 600)
+    currencyOpertionType = '';
   }
 };
 
 const setLocalSelectCurrencyInfo = (params = {}) => {
-    setChromeStorage({ selectCurrencyInfo : JSON.stringify(params)})    
+  setChromeStorage({ selectCurrencyInfo: JSON.stringify(params) })
 }
 
 const cancelDeposit = () => {
@@ -282,7 +267,7 @@ const cancelDeposit = () => {
 }
 
 const confirmDeposit = (params) => {
-  if(reqCalcIng) {
+  if (reqCalcIng) {
     return;
   }
 
@@ -290,16 +275,18 @@ const confirmDeposit = (params) => {
   depositDesc.value = '';
 
   let achPayInfo = {
-      amountValue: finalAmountData.value.finalAmountValue
+    amountValue: finalAmountData.value.finalAmountValue
   };
-  let guideUrl = chrome.runtime.getURL('/iframe/ach-cashier.html');
-  setChromeStorage({ achPayInfo : JSON.stringify(achPayInfo)});
+  let guideUrl = chromeExtensionUrl + ('iframe/ach-cashier.html');
+  setChromeStorage({ achPayInfo: JSON.stringify(achPayInfo) });
   let str = window.location.hash + '&refresh=true';
   let path = str.substring(1, str.length);
-  setChromeStorage({ achPayData : JSON.stringify({
-    form: 'popupPage',
-    path
-  })});
+  setChromeStorage({
+    achPayData: JSON.stringify({
+      form: 'popupPage',
+      path
+    })
+  });
 
   chrome.tabs.create({
     url: guideUrl
@@ -307,23 +294,23 @@ const confirmDeposit = (params) => {
 }
 
 const onDepositAmountInput = async (params = {}) => {
-  let {inputVal} = params;
+  let { inputVal } = params;
   reqCalcIng = true;
-  if(inputVal === '') {
+  if (inputVal === '') {
     inputVal = 0;
   }
   let res = await payCalcFee({
-      params: {
-          amountValue: inputVal,
-          currencyCode: currencyInfo.value.currencyCode,
-          payChannel: 'ach',
-      },
+    params: {
+      amountValue: inputVal,
+      currencyCode: currencyInfo.value.currencyCode,
+      payChannel: 'ach',
+    },
   });
   reqCalcIng = false;
-  if(res.code == 0) {
-    let {feeAmountValue, feeDesc} = res.data;
+  if (res.code == 0) {
+    let { feeAmountValue, feeDesc } = res.data;
     finalAmountData.value = res.data;
-    if(inputVal === 0) {
+    if (inputVal === 0) {
       depositDesc.value = `${feeDesc}`;
     } else {
       depositDesc.value = `Charge Fee:${feeAmountValue} USD(${feeDesc})`;
@@ -333,47 +320,47 @@ const onDepositAmountInput = async (params = {}) => {
 
 
 const onMessage = () => {
-    chrome.runtime.onMessage.addListener(msgListener)
+  chrome.runtime.onMessage.addListener(msgListener)
 }
 
 const msgListener = (req, sender, sendResponse) => {
-    switch (req.actionType) {
-        case 'CONTENT_POPUP_PAGE_SHOW':
-            let {refresh = false} = router.currentRoute.value.query;
-            if(refresh && currencyInfo.value.tokenSymbol) {
-              onRefresh();
-            }
-            break;
-    }
+  switch (req.actionType) {
+    case 'CONTENT_POPUP_PAGE_SHOW':
+      let { refresh = false } = router.currentRoute.value.query;
+      if (refresh && currencyInfo.value.tokenSymbol) {
+        onRefresh();
+      }
+      break;
+  }
 }
 
 onMounted(() => {
-    let {params = '{}'} = router.currentRoute.value.query;
-
-    let {currencies = [], totalBalance = 0, totalUsdEstimateBalance = 0} =  JSON.parse(params);
-
-    currenciesData.value = currencies;
-    if(currencies.length) {
-      currencyInfo.value = {
-        ...currencies[0],
-        totalBalance,
-        totalUsdEstimateBalance
-      };
-      if(currencies.length == 1) {
-        enableRecharge.value = currencyInfo.value.enableRecharge;
-        enableWithdraw.value = currencyInfo.value.enableWithdraw;
-      }
-    } 
-    if(window.location.pathname.indexOf('/home.html') > -1) {
-      showSendBtn.value = false;
-    } else {
-      showSendBtn.value = true;
+  let { params = '{}' } = router.currentRoute.value.query;
+
+  let { currencies = [], totalBalance = 0, totalUsdEstimateBalance = 0 } = JSON.parse(params);
+
+  currenciesData.value = currencies;
+  if (currencies.length) {
+    currencyInfo.value = {
+      ...currencies[0],
+      totalBalance,
+      totalUsdEstimateBalance
+    };
+    if (currencies.length == 1) {
+      enableRecharge.value = currencyInfo.value.enableRecharge;
+      enableWithdraw.value = currencyInfo.value.enableWithdraw;
     }
-    onMessage();
+  }
+  if (window.location.pathname.indexOf('/home.html') > -1) {
+    showSendBtn.value = false;
+  } else {
+    showSendBtn.value = true;
+  }
+  onMessage();
 })
 
 onBeforeUnmount(() => {
-    chrome.runtime.onMessage.removeListener(msgListener);
+  chrome.runtime.onMessage.removeListener(msgListener);
 })
 
 </script>
@@ -406,6 +393,7 @@ onBeforeUnmount(() => {
       justify-content: center;
       flex-direction: column;
       width: 100%;
+
       .balance {
         padding: 0 18px;
         box-sizing: border-box;
@@ -415,7 +403,7 @@ onBeforeUnmount(() => {
         align-items: center;
         justify-content: center;
 
-        .symbol{
+        .symbol {
           word-break: break-all;
         }
       }
@@ -433,6 +421,7 @@ onBeforeUnmount(() => {
       }
     }
   }
+
   .bottom {
     height: 162px;
     padding: 0 20px;
@@ -469,6 +458,7 @@ onBeforeUnmount(() => {
       margin-bottom: 18px;
       background: #1d9bf0;
       color: #fff;
+
       img {
         width: 19px;
         height: 19px;
@@ -505,25 +495,26 @@ onBeforeUnmount(() => {
 
 
   .selectDiv {
-      position: absolute;
-      z-index: 1000;
-      width: 100%;
-      max-height: 480px;
-      padding-bottom: 30px;
-      left: 0;
-      bottom: 0;
-      background-color: #fff;
-      border-radius: 20px 20px 0 0;
-      overflow-y: auto;
+    position: absolute;
+    z-index: 1000;
+    width: 100%;
+    max-height: 480px;
+    padding-bottom: 30px;
+    left: 0;
+    bottom: 0;
+    background-color: #fff;
+    border-radius: 20px 20px 0 0;
+    overflow-y: auto;
   }
+
   .selectBg {
-      position: absolute;
-      z-index: 999;
-      top: 0;
-      left: 0;
-      width: 100%;
-      height: 100%;
-      background: rgba($color: #000000, $alpha: 0.6);
+    position: absolute;
+    z-index: 999;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba($color: #000000, $alpha: 0.6);
   }
 }
 </style>

+ 5 - 2
src/view/popup/tabbar-page/wallter/popup.vue

@@ -25,7 +25,7 @@
             </div>
         </div>
 
-        <currency-list 
+        <currency-list
             v-if="userInfo.accessToken"
             style="height: calc(100% - 103px);"
             ref="currencyListDom"
@@ -90,13 +90,16 @@ const init = () => {
     checkLoginState((res) => {
         if (res) {
             getAccountBalance();
+            setMessageCount();
+            if(window.location.pathname.indexOf('popup-page.html') > -1) {
+              return
+            }
             Report.reportLog({
                 pageSource: Report.pageSource.denetHomePage,
                 businessType: Report.businessType.pageView,
             }, {
                 type: window.location.href.indexOf('home.html') > -1 ? 'web' : 'extensions'
             });
-            setMessageCount();
         } else {
             Report.reportLog({
                 pageSource: Report.pageSource.denetLogin,

Неке датотеке нису приказане због велике количине промена