소스 검색

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,

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.