nieyuge vor 2 Jahren
Ursprung
Commit
f4764d86e5
33 geänderte Dateien mit 1344 neuen und 171 gelöschten Zeilen
  1. 3 0
      src/assets/svg/icon-post-edit-luck.svg
  2. 3 0
      src/assets/svg/icon-post-edit-open.svg
  3. 4 0
      src/assets/svg/icon-post-lock.svg
  4. 6 0
      src/entry/content.js
  5. 8 0
      src/http/nft.js
  6. 9 1
      src/http/toolBoxApi.js
  7. 5 1
      src/iframe/nft-card.js
  8. 3 1
      src/iframe/publish.js
  9. 8 0
      src/iframe/tool-box-buy-nft.js
  10. 25 1
      src/log-center/logEnum.js
  11. 7 0
      src/log-center/logger.js
  12. 75 39
      src/logic/background/twitter.js
  13. 24 0
      src/logic/content/ToolBox.js
  14. 17 0
      src/logic/content/nft.js
  15. 42 14
      src/logic/content/twitter.js
  16. 3 2
      src/manifest.json
  17. 13 9
      src/uilts/chromeExtension.js
  18. 44 34
      src/view/components/popup-transactions.vue
  19. 19 1
      src/view/iframe/buy-nft/buy/home.vue
  20. 12 0
      src/view/iframe/buy-nft/buy/open-box.vue
  21. 37 0
      src/view/iframe/buy-nft/buy/pay.vue
  22. 3 1
      src/view/iframe/buy-nft/index.vue
  23. 17 2
      src/view/iframe/nft/card.vue
  24. 182 0
      src/view/iframe/publish/components/nft-setting.vue
  25. 17 4
      src/view/iframe/publish/components/select-publish-content.vue
  26. 43 3
      src/view/iframe/publish/tool-box/child/editor.vue
  27. 8 0
      src/view/iframe/publish/tool-box/child/guide.vue
  28. 37 23
      src/view/iframe/publish/tool-box/child/preview.vue
  29. 10 1
      src/view/iframe/publish/tool-box/index.vue
  30. 198 0
      src/view/iframe/tool-box/buy-nft.vue
  31. 325 20
      src/view/iframe/tool-box/card.vue
  32. 133 5
      src/view/iframe/tool-box/full.vue
  33. 4 9
      src/view/popup/tabbar-page/message/index.vue

+ 3 - 0
src/assets/svg/icon-post-edit-luck.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 fill-rule="evenodd" clip-rule="evenodd" d="M5.05497 9.83636V7.82727C5.05497 6.12727 6.29133 4.89091 7.99133 4.89091H9.2277C10.7732 4.89091 12.1641 6.12727 12.1641 7.82727V9.83636H13.555V7.82727C13.555 5.35455 11.5459 3.5 9.2277 3.5H7.99133C5.51861 3.5 3.66406 5.50909 3.66406 7.82727V9.83636H5.05497ZM14.3273 20.5003H2.89091C2.11818 20.5003 1.5 19.8821 1.5 19.1094V12.0003C1.5 11.2276 2.27273 10.6094 2.89091 10.6094H14.1727C15.1 10.6094 15.5636 11.2276 15.5636 12.0003V19.1094C15.7182 19.8821 15.1 20.5003 14.3273 20.5003ZM20.1177 20.5458L21.8908 18.7097L21.7607 11.2568C22.0825 11.0797 22.381 10.8534 22.6513 10.5734C23.3567 9.84292 23.743 8.86219 23.7253 7.84692C23.7076 6.83165 23.2873 5.865 22.5569 5.15962C21.8264 4.45425 20.8457 4.06793 19.8304 4.08565C18.8151 4.10337 17.8485 4.52368 17.1431 5.25412C16.4377 5.98455 16.0514 6.96528 16.0691 7.98056C16.0869 8.99583 16.5072 9.96248 17.2376 10.6679C17.5176 10.9382 17.8237 11.154 18.1516 11.3198L18.1871 13.359L19.5642 14.6888L18.2344 16.0658L19.6115 17.3957L18.2816 18.7727L20.1177 20.5458ZM19.8592 5.73542C20.1976 5.72951 20.5245 5.85828 20.768 6.09341C21.0115 6.32853 21.1516 6.65075 21.1575 6.98917C21.1634 7.3276 21.0346 7.65451 20.7995 7.89799C20.5644 8.14147 20.2422 8.28157 19.9038 8.28748C19.5653 8.29339 19.2384 8.16461 18.9949 7.92949C18.7515 7.69436 18.6114 7.37215 18.6055 7.03372C18.5995 6.6953 18.7283 6.36839 18.9634 6.12491C19.1986 5.88143 19.5208 5.74132 19.8592 5.73542Z" fill="#424B51"/>
+</svg>

+ 3 - 0
src/assets/svg/icon-post-edit-open.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="M11.5957 5.58382C12.4466 5.58382 13.2627 5.92184 13.8643 6.52352C14.466 7.1252 14.804 7.94125 14.804 8.79215C14.804 9.64306 14.466 10.4591 13.8643 11.0608C13.2627 11.6625 12.4466 12.0005 11.5957 12.0005C10.7448 12.0005 9.92875 11.6625 9.32707 11.0608C8.72539 10.4591 8.38737 9.64306 8.38737 8.79215C8.38737 7.94125 8.72539 7.1252 9.32707 6.52352C9.92875 5.92184 10.7448 5.58382 11.5957 5.58382ZM5.17904 8.00049C5.69237 8.00049 6.16904 8.13799 6.58154 8.38549C6.44404 9.69632 6.82904 10.998 7.61737 12.0155C7.15904 12.8955 6.24237 13.5005 5.17904 13.5005C4.44969 13.5005 3.75022 13.2108 3.23449 12.695C2.71877 12.1793 2.42904 11.4798 2.42904 10.7505C2.42904 10.0211 2.71877 9.32167 3.23449 8.80594C3.75022 8.29022 4.44969 8.00049 5.17904 8.00049ZM18.0124 7.85352C18.7417 7.85352 19.4412 8.14325 19.9569 8.65897C20.4726 9.1747 20.7624 9.87417 20.7624 10.6035C20.7624 11.3329 20.4726 12.0323 19.9569 12.5481C19.4412 13.0638 18.7417 13.3535 18.0124 13.3535C16.949 13.3535 16.0324 12.7485 15.574 11.8685C16.3624 10.851 16.7474 9.54935 16.6099 8.23852C17.0224 7.99102 17.499 7.85352 18.0124 7.85352ZM5.63737 16.791C5.63737 14.8935 8.30487 13.3535 11.5957 13.3535C14.8865 13.3535 17.554 14.8935 17.554 16.791V18.3952H5.63737V16.791ZM0.595703 18.3952V17.0202C0.595703 15.746 2.3282 14.6735 4.67487 14.3619C4.13404 14.9852 3.80404 15.8468 3.80404 16.791V18.3952H0.595703ZM22.5957 18.3952H19.3874V16.791C19.3874 15.8468 19.0574 14.9852 18.5165 14.3619C20.8632 14.6735 22.5957 15.746 22.5957 17.0202V18.3952Z" fill="#424B51"/>
+</svg>

+ 4 - 0
src/assets/svg/icon-post-lock.svg

@@ -0,0 +1,4 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M72.0799 86.2749H27.4304C24.4135 86.2749 22 83.6649 22 80.4025V50.388C22 47.1256 25.0169 44.5156 27.4304 44.5156H71.4766C75.0968 44.5156 76.9069 47.1256 76.9069 50.388V80.4025C77.5103 83.6649 75.0968 86.2749 72.0799 86.2749Z" fill="#F3B14D"/>
+<path d="M35.1867 40.4444V33.8186C35.1867 26.8184 40.1651 21.7274 47.0105 21.7274H51.989C58.212 21.7274 63.8128 26.8184 63.8128 33.8186V40.4444H69.4135V33.8186C69.4135 23.6366 61.3236 16 51.989 16H47.0105C37.0536 16 29.5859 24.2729 29.5859 33.8186V40.4444H35.1867Z" fill="#AEB9C2"/>
+</svg>

+ 6 - 0
src/entry/content.js

@@ -219,5 +219,11 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
         case 'Set_ToolBox_Fixed':
             toolBox.switchStatus(req)
             break
+        case 'Set_ToolBox_By_Nft':
+            toolBox.buyNft(req)
+            break;
+        case 'Hide_ToolBox_By_Nft':
+            toolBox.hideBuyNft(req)
+            break;
     }
 })

+ 8 - 0
src/http/nft.js

@@ -87,4 +87,12 @@ export function redeemNft(params) {
         method: 'post',
         data: params
     })
+}
+
+export function listPossessNftProject(params) {
+    return service({
+        url: `/nft/possess/listPossessNftProject`,
+        method: 'post',
+        data: params
+    })
 }

+ 9 - 1
src/http/toolBoxApi.js

@@ -30,4 +30,12 @@ export function checkInputUrlInBlacklist(params) {
         method: 'post',
         data: params
     })
-}
+}
+
+export function getPostEditorNftCertInfo(params) {
+    return service({
+        url: `/post/editor/getPostEditorNftCertInfo`,
+        method: 'post',
+        data: params
+    })
+}

+ 5 - 1
src/iframe/nft-card.js

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

+ 3 - 1
src/iframe/publish.js

@@ -3,7 +3,7 @@ import App from '@/view/iframe/publish/publish.vue'
 
 import "ant-design-vue/dist/antd.css"; // or 'ant-design-vue/dist/antd.less'
 
-import { Button, message, Tooltip, Switch } from "ant-design-vue";
+import { Button, message, Tooltip, Switch, Radio, RadioGroup } from "ant-design-vue";
 
 import AutoLog from '@/log-center/autoLog';
 
@@ -20,6 +20,8 @@ app.use(Tooltip);
 app.use(message);
 app.use(Switch);
 app.use(AutoLog);
+app.use(Radio);
+app.use(RadioGroup);
 
 
 import CoutomSentry from "@/uilts/sentry.js"

+ 8 - 0
src/iframe/tool-box-buy-nft.js

@@ -0,0 +1,8 @@
+import { createApp } from 'vue'
+import App from '@/view/iframe/tool-box/buy-nft.vue'
+import AutoLog from '@/log-center/autoLog';
+
+const app = createApp(App);
+
+app.use(AutoLog);
+app.mount('#app');

+ 25 - 1
src/log-center/logEnum.js

@@ -4,6 +4,13 @@ export const logType = {
     'denet': '150',//denet-event-log
 }
 
+export const redPacketType = {
+    nftSale: 2,
+    nftGroupSale: 3,
+    treasure: 4,
+    postEditor: 5,
+}
+
 export const businessType = {
     buttonView: "buttonView",
     buttonClick: "buttonClick",
@@ -58,6 +65,15 @@ export const objectType = {
     create_nfts_button: 'create-nfts-button',
     confirm_transfer_button: 'confirm-transfer-button',
     redeem_button: 'redeem-button',
+    buy_button: 'buy-button',
+    buy_nft_button: 'buy-nft-button',
+    custom_link_button: 'custom-link-button',
+    history_button: 'history-button',
+    app_button: 'app-button',
+    enter_url_button: 'enter-url-button',
+    top_right_button: 'top-right-button',
+    fullscreen_button: 'fullscreen-button',
+    encrypte_nft_button: 'encrypte-nft-button',
 }
 
 export const pageSource = {
@@ -75,6 +91,7 @@ export const pageSource = {
     denetMorePage: "denet-more-page",
     denetSelector: "denet-selector",
     nftShopPage: "nft-shop-page",
+    nftPreviewPage: "nft-preview-page",
     denetNftTransferPage: "denet-nft-transfer-page",
     // 待开红包页
     pending_page: 'pending-page',
@@ -91,7 +108,14 @@ export const pageSource = {
     // 成功领取到钱包
     received_success_page: 'received-success-page',
     received_empty_rewards_page: 'received-empty-rewards-page',
-
+    pe_loading_page: 'pe-loading-page',
+    pe_display_page: 'pe-display-page',
+    nft_sales_window: 'nft-sales-window',
+    nft_post_page: 'nft-post-page',
+    main_page_dashboard: 'main-page-dashboard',
+    post_editor_guide_page_left: 'post-editor-guide-page-left',
+    post_editor_guide_page_right: 'post-editor-guide-page-right',
+    buy_posteditor_nft_dialog: 'buy-posteditor-nft-dialog',
 }
 
 export const extParams = {

+ 7 - 0
src/log-center/logger.js

@@ -9,6 +9,13 @@ let mid = '';
  * @extParams 最终上报到阿里云以json字符串存储的参数,如果extparams传入的不是obj会转换成obj
  */
 export async function reportLog(eventData = {}, extParams = {}) {
+    // 过滤空值
+    let dataKey = Object.keys(eventData);
+    dataKey.forEach(key => {
+        if (eventData[key] === '') {
+            delete eventData[key]
+        }
+    })
     // 2.reportLog 异常 存储到本地,再上报
     try {
         if (!userInfo) {

+ 75 - 39
src/logic/background/twitter.js

@@ -244,21 +244,23 @@ export function onInstalledUserSet() {
         chrome.action.getUserSettings().then(res => {
             setChromeStorage({ userSettings: JSON.stringify({ res }) })
             // 无刷新插入js
-            chrome.tabs.query({}, (tab) => {
-                for (let i in tab) {
-                    chrome.scripting.executeScript({
-                        target: { tabId: tab[i].id },
-                        files: ['js/content_help.js']
-                    }, () => { })
-                    if (tab[i].url.indexOf('twitter.com') >= 0 || tab[i].url.indexOf('facebook.com') >= 0) {
+            chrome.tabs.query({}, (tabs) => {
+                for (let i in tabs) {
+                    if (tabs[i].url && tabs[i].url.substr(0, 4).includes('http')) {
                         chrome.scripting.executeScript({
-                            target: { tabId: tab[i].id },
-                            files: ['js/content.js'],
-                        }, () => {
-                            setTimeout(() => {
-                                setChromeStorage({ executeScript: JSON.stringify({ executeScript: 1 }) })
-                            }, 2000);
-                        })
+                            target: { tabId: tabs[i].id },
+                            files: ['js/content_help.js']
+                        }, () => { })
+                        if (tabs[i].url.indexOf('twitter.com') >= 0 || tabs[i].url.indexOf('facebook.com') >= 0) {
+                            chrome.scripting.executeScript({
+                                target: { tabId: tabs[i].id },
+                                files: ['js/content.js'],
+                            }, () => {
+                                setTimeout(() => {
+                                    setChromeStorage({ executeScript: JSON.stringify({ executeScript: 1 }) })
+                                }, 2000);
+                            })
+                        }
                     }
                 }
             })
@@ -276,14 +278,22 @@ export function onInstalledUserSet() {
  * 检查是否pined 显示tips
  */
 export function checkPined() {
-    chrome.action.getUserSettings(res => {
-        let { isOnToolbar } = res;
-        if (!isOnToolbar) {
-            sendActivetabMessage({
-                actionType: 'BG_SHOW_PIN_TIPS'
-            });
-        }
-    })
+    try {
+        chrome.action.getUserSettings(res => {
+            let { isOnToolbar } = res;
+            if (!isOnToolbar) {
+                sendActivetabMessage({
+                    actionType: 'BG_SHOW_PIN_TIPS'
+                });
+            }
+        })
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'checkPined',
+            errMsg: error.message
+        })
+    }
 }
 
 function sendActivetabMessage(message = {}) {
@@ -292,9 +302,11 @@ function sendActivetabMessage(message = {}) {
             active: true,
             currentWindow: true
         }, (tabs) => {
-            chrome.tabs.sendMessage(tabs[0].id, message, res => {
-                console.log(res)
-            })
+            if(tabs && tabs.length) {
+                chrome.tabs.sendMessage(tabs[0].id, message, res => {
+                    console.log(res)
+                })
+            }
         })
     } catch (error) {
         Report.reportLog({
@@ -427,26 +439,50 @@ export function onInstalledCreateTab() {
  * @param {*} req 
  */
 export function popupRePublish(req) {
-    setChromeStorage({
-        popupShowPublishDialog: JSON.stringify({
-            ...req.data,
-            show: true
-        }),
-    });
-    chrome.tabs.create({
-        url: "https://twitter.com",
-    });
+    try {
+        setChromeStorage({
+            popupShowPublishDialog: JSON.stringify({
+                ...req.data,
+                show: true
+            }),
+        });
+        chrome.tabs.create({
+            url: "https://twitter.com",
+        });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'popupRePublish',
+            errMsg: error.message
+        })
+    }
 }
 
 export function setBadgeInfo(params) {
-    let { text = '', color = '#DF3535' } = params.data || {};
-    chrome.action.setBadgeText({ text: text });
-    chrome.action.setBadgeBackgroundColor({ color: color });
+    try {
+        let { text = '', color = '#DF3535' } = params.data || {};
+        chrome.action.setBadgeText({ text: text });
+        chrome.action.setBadgeBackgroundColor({ color: color });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'setBadgeInfo',
+            errMsg: error.message
+        })
+    }
 }
 
 export function hideBadge() {
-    chrome.action.setBadgeText({ text: '' });
-    chrome.action.setBadgeBackgroundColor({ color: [0, 0, 0, 0] });
+    try {
+        chrome.action.setBadgeText({ text: '' });
+        chrome.action.setBadgeBackgroundColor({ color: [0, 0, 0, 0] });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'hideBadge',
+            errMsg: error.message
+        })
+    }
 }
 
 export async function setMessageCount() {

+ 24 - 0
src/logic/content/ToolBox.js

@@ -19,6 +19,7 @@ export const toolBox = new class ToolBox {
             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.allow = "camera *;microphone *"
         document.body.append(iframe)
     }
     // 切换状态
@@ -55,4 +56,27 @@ export const toolBox = new class ToolBox {
                 break
         }
     }
+    // 购买NFT
+    buyNft(req) {
+        let iframe = document.createElement('iframe')
+            iframe.src = chrome.runtime.getURL('/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 = `
+                ${iframe.outerHTML}
+                <div class="mask_bg"></div>
+                <style>
+                    #denet-tool-box-buy-nft { position:fixed; width:100%; height:100%; top:0; left:0; }
+                    #denet-tool-box-buy-nft iframe { position:absolute; z-index:33; top:0; left:0; width:100%; height:100%; border:medium none; }
+                    #denet-tool-box-buy-nft .mask_bg{  position:absolute; z-index:32; width:100%; height:100%; top:0; left:0; background-color:rgba(0,0,0,.5); }
+                </style>
+            `
+        document.body.append(div)
+    }
+    hideBuyNft() {
+        let node = document.querySelector('#denet-tool-box-buy-nft')
+        node && node.remove()
+    }
 }

+ 17 - 0
src/logic/content/nft.js

@@ -3,6 +3,7 @@ import { listJoinNftGroup } from '@/http/nft';
 import { getChromeStorage } 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"
 
 var ifShowNftGroup = false;
 var tempNftGroupPost = null;
@@ -31,8 +32,24 @@ export const showNFTGroupIcon = () => {
             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({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonView,
+            objectType: Report.objectType.buttonSecond
+        }, {
+            type: 2
+        });
     }
 }
 

+ 42 - 14
src/logic/content/twitter.js

@@ -31,11 +31,11 @@ function twitterPinLogin() {
     if (pin_login) {
         return
     }
-    pin_login = true
     if (window.location.href == 'https://api.twitter.com/oauth/authorize') {
         let code = document.querySelector('code')
 
         if (code) {
+            pin_login = true
             chrome.runtime.sendMessage({ actionType: "CONTENT_SEND_CODE", code: code.innerText }, () => { })
             // port.postMessage({ state: 'CONTENT_SEND_CODE', code: code.innerText })
         }
@@ -276,42 +276,60 @@ function checkIsShowReSend(dom, params) {
  * @param isClick
  * @private
  */
-function _addDeNetEditBtn(params = {}) {
+ function _addDeNetEditBtn(params = {}) {
     let toolElem = document.querySelector('div[data-testid="toolBar"]');
     if (toolElem) {
-        Report.reportLog({
-            pageSource: Report.pageSource.mainPage,
-            businessType: Report.businessType.buttonView,
-            objectType: Report.objectType.buttonSecond
-        });
         let innerDeIcon = toolElem.querySelector('#de-btn1');
         if (!innerDeIcon) {
             toolElem.firstChild.appendChild(createTweetToolbarDenet());
             popupShowGiveawayDialog();
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 0
+            });
         }
 
         let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
         if (!innerToolBoxIcon) {
             toolElem.firstChild.appendChild(createTweetToolbarToolBox())
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 1
+            });
         }
     } else {
         setTimeout(() => {
             let toolElem = document.querySelector('div[data-testid="toolBar"]');
             if (toolElem) {
-                Report.reportLog({
-                    pageSource: Report.pageSource.mainPage,
-                    businessType: Report.businessType.buttonView,
-                    objectType: Report.objectType.buttonSecond
-                });
                 let innerDeIcon = toolElem.querySelector('#de-btn1');
                 if (!innerDeIcon) {
                     toolElem.firstChild.appendChild(createTweetToolbarDenet());
                     popupShowGiveawayDialog();
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    }, {
+                        type: 0
+                    });
                 }
 
                 let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
                 if (!innerToolBoxIcon) {
                     toolElem.firstChild.appendChild(createTweetToolbarToolBox())
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    }, {
+                        type: 1
+                    });
                 }
             }
         }, 1000)
@@ -594,6 +612,8 @@ function createTweetToolbarDenet() {
             pageSource: Report.pageSource.mainPage,
             businessType: Report.businessType.buttonClick,
             objectType: Report.objectType.buttonSecond
+        }, {
+            type: 0
         });
         _deNetBtnClick();
     })
@@ -614,6 +634,14 @@ function createTweetToolbarToolBox() {
         _deNetBtnClick({
             type: 'TOOL_BOX'
         })
+        // report
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.buttonSecond
+        }, {
+            type: 1
+        });
     })
 
     return deToolBoxBtn;
@@ -1716,13 +1744,13 @@ export const hideBuyNFT = () => {
     iframe.src = ''
 }
 
-export const showBuyNFT = ({ nft_project_Id }) => {
+export const showBuyNFT = ({ nft_project_Id, post_Id = '' }) => {
     if (!nft_project_Id) {
         return
     }
     let iframe = document.querySelector('#nftProjectId')
     iframe.style.display = 'block'
-    iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/?nftProjectId=${nft_project_Id}`)
+    iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/?nftProjectId=${nft_project_Id}&postId=${post_Id}`)
 }
 
 const initBuyNFT = () => {

+ 3 - 2
src/manifest.json

@@ -2,8 +2,8 @@
     "manifest_version": 3,
     "name": "DeNet",
     "description": "Growing more twitter followers with Denet",
-    "version": "1.1.6.1",
-    "denet_app_version_code": "18",
+    "version": "1.1.6.2",
+    "denet_app_version_code": "19",
     "background": {
         "service_worker": "/js/background.js"
     },
@@ -95,6 +95,7 @@
                 "/iframe/joined-group-list.html",
                 "/iframe/tool-box-guide.html",
                 "/iframe/tool-box.html",
+                "/iframe/tool-box-buy-nft.html",
                 "/iframe/test.html",
                 "/iframe/ach-cashier.html",
                 "/img/icon-denet-logo.svg",

+ 13 - 9
src/uilts/chromeExtension.js

@@ -141,15 +141,19 @@ export function checkIsLogin(callback) {
 
 let callback_arr = []
 export function httpContentToBack(data, callback) {
-    let callback_id = guid()
-    chrome.runtime.sendMessage({ actionType: "HTTP_CONTENT_TO_BACK", data, callback_id }, (res) => {
-        if (res && callback) {
-            callback_arr.push({
-                callback_id,
-                callback,
-            })
-        }
-    })
+    try {
+        let callback_id = guid()
+        chrome.runtime.sendMessage({ actionType: "HTTP_CONTENT_TO_BACK", data, callback_id }, (res) => {
+            if (res && callback) {
+                callback_arr.push({
+                    callback_id,
+                    callback,
+                })
+            }
+        })
+    } catch (error) {
+
+    }
 }
 
 // 再找到它执行

+ 44 - 34
src/view/components/popup-transactions.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="com-wrapper" ref="listWrapper"  @scroll="listScroll">
+    <div class="com-wrapper" ref="listWrapper" @scroll="listScroll">
         <!-- <div class="com-nav-bar">
             <img
                 :src="require('@/assets/svg/icon-bar-arrow-left.svg')"
@@ -9,14 +9,13 @@
             Transactions
         </div> -->
 
-            <template v-if="!dataList.length">
-                <img class="icon-empty" :src="require('@/assets/svg/icon-empty-list.svg')" />
-            </template>
+        <template v-if="!dataList.length">
+            <img class="icon-empty" :src="require('@/assets/svg/icon-empty-list.svg')" />
+        </template>
         <div class="list-wrapper" ref="listContent">
             <div>
                 <div class="cell" v-for="(item, index) in dataList" :key="index">
-                    <red-dot class="red-dots"
-                        v-if="item.unReadMsgCount > 0 && isReadMsg"></red-dot>
+                    <red-dot class="red-dots" v-if="item.unReadMsgCount > 0 && isReadMsg"></red-dot>
                     <div class="img-wrapper">
                         <!-- 收入- 任务红包领取 -->
                         <template v-if="item.bizType == 1 || item.bizType == 5 || item.bizType == 10 || item.bizType == 11 || item.bizType == 12">
@@ -44,14 +43,18 @@
                         </template>
                         <!-- 收入 - 盲盒 -->
                         <template v-else-if="item.bizType == 7">
-                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath" v-if="item.bizData && item.bizData.imagePath" />
-                            <img class="icon-avatar" style="margin-left:-4px" :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
+                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath"
+                                v-if="item.bizData && item.bizData.imagePath" />
+                            <img class="icon-avatar" style="margin-left:-4px"
+                                :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-list-withdraw-s.svg')" />
                         </template>
                         <!-- 收入 - 盲盒 -->
                         <template v-else-if="item.bizType == 8">
-                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath" v-if="item.bizData && item.bizData.imagePath" />
-                            <img class="icon-avatar" style="margin-left:-4px" :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
+                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath"
+                                v-if="item.bizData && item.bizData.imagePath" />
+                            <img class="icon-avatar" style="margin-left:-4px"
+                                :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-get-giveaways-s.svg')" />
                         </template>
                         <!-- 支出 - 提现 -->
@@ -72,12 +75,12 @@
                         <!-- 支出-买盲盒 -->
                         <template v-else-if="item.bizType == -3">
                             <img style="margin-left:-4px" :src="
-                                        require('@/assets/svg/icon-wallter-list-blind-box.svg')
+                                require('@/assets/svg/icon-wallter-list-blind-box.svg')
                             " />
                         </template>
                         <template v-else-if="item.bizType == -4">
                             <img class="icon-avatar" style="margin-left:-4px" :src="
-                                        require('@/assets/svg/icon-big-give.svg')
+                                require('@/assets/svg/icon-big-give.svg')
                             " />
                             <img class="icon-give" :src="
                                 require('@/assets/svg/icon-list-withdraw-s.svg')
@@ -85,8 +88,10 @@
                         </template>
                         <!-- 交易链手续费 -->
                         <template v-else-if="item.bizType == -5">
-                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath" v-if="item.bizData && item.bizData.imagePath" />
-                            <img class="icon-avatar" style="margin-left:-4px" :src="require('@/assets/img/icon-box2.png')" v-else />
+                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath"
+                                v-if="item.bizData && item.bizData.imagePath" />
+                            <img class="icon-avatar" style="margin-left:-4px"
+                                :src="require('@/assets/img/icon-box2.png')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-transaction-s.svg')" />
                         </template>
                         <!-- 支出-夺宝 -->
@@ -121,7 +126,7 @@
                                     Lottery Refund
                                 </template>
                                 <template v-else-if="item.bizType == 7">
-                                    Sell NFT Mystery box*{{(item.bizData && item.bizData.nftItemCount || '')}}
+                                    Sell NFT Mystery box*{{ (item.bizData && item.bizData.nftItemCount || '') }}
                                 </template>
                                 <template v-else-if="item.bizType == 8">
                                     NFT Refund
@@ -139,7 +144,7 @@
                                     Giveaways
                                 </template>
                                 <template v-else-if="item.bizType == -3">
-                                    Buy NFT Mystery box*{{(item.bizData && item.bizData.nftItemCount || '')}}
+                                    Buy NFT Mystery box*{{ (item.bizData && item.bizData.nftItemCount || '') }}
                                 </template>
                                 <template v-else-if="item.bizType == -4">
                                     Lottery Giveaway
@@ -157,17 +162,19 @@
                             <div class="msg">
                                 <template v-if="item.bizType == -1">
                                     <!-- 提现支出-状态(0:已申请,1:支付中,2:提现成功,3:提现失败) -->
-                                    <template v-if="item.bizData.withdrawStatus == 0 || item.bizData.withdrawStatus == 1">
+                                    <template
+                                        v-if="item.bizData.withdrawStatus == 0 || item.bizData.withdrawStatus == 1">
                                         <div>
                                             <div class="balance"
-                                                :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                                :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
                                                 <span class="amount">
-                                                    <a-tooltip :title="'-'+item.trxAmountValue">
+                                                    <a-tooltip :title="'-' + item.trxAmountValue">
                                                         -{{ getBit(item.trxAmountValue) || 0 }}
                                                     </a-tooltip>
                                                 </span>
                                                 <div class="trx-amount-currency-info">
-                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol }}</span>
+                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol
+                                                    }}</span>
                                                     <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
                                                 </div>
                                             </div>
@@ -178,9 +185,9 @@
                                     </template>
                                     <template v-else-if="item.bizData.withdrawStatus == 2">
                                         <div class="balance"
-                                            :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                            :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
                                             <span class="amount">
-                                                <a-tooltip :title="'-'+item.trxAmountValue">
+                                                <a-tooltip :title="'-' + item.trxAmountValue">
                                                     -{{ getBit(item.trxAmountValue) || 0 }}
                                                 </a-tooltip>
                                             </span>
@@ -200,7 +207,8 @@
                                                     </a-tooltip>
                                                 </span>
                                                 <div class="trx-amount-currency-info">
-                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol }}</span>
+                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol
+                                                    }}</span>
                                                     <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
                                                 </div>
                                             </div>
@@ -211,9 +219,9 @@
                                     </template>
                                     <template v-else>
                                         <div class="balance"
-                                            :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                            :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
                                             <span class="amount">
-                                                <a-tooltip :title="'-'+item.trxAmountValue">
+                                                <a-tooltip :title="'-' + item.trxAmountValue">
                                                     -{{ getBit(item.trxAmountValue) || 0 }}
                                                 </a-tooltip>
                                             </span>
@@ -227,7 +235,7 @@
 
                                 <template v-else>
                                     <div class="balance"
-                                        :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                        :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
 
                                         <!--支出—— -2:零钱余额支付 、-3: NFT盲盒余额支付 -->
                                         <span class="amount" v-if="item.bizType == -2 || item.bizType == -3 || item.bizType == -4 || item.bizType == -5 || item.bizType == -6">
@@ -237,7 +245,7 @@
                                         </span>
                                         <!-- 收入—— bizType:1、2、3、4 -->
                                         <span class="amount" v-else>
-                                            <a-tooltip :title="'+'+item.trxAmountValue">
+                                            <a-tooltip :title="'+' + item.trxAmountValue">
                                                 +{{ getBit(item.trxAmountValue) || 0 }}
                                             </a-tooltip>
                                         </span>
@@ -325,13 +333,15 @@ onMounted(() => {
 });
 
 const setMessageCount = () => {
-    getAllMessageInfo({params: {
-    }}).then(res => {
-        if(res.code == 0) {
-            let {unReadCountTotal = 0 } = res.data;
-            if(unReadCountTotal > 0) {
-                let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal+'';
-                setBadgeInfo({data: {text}});
+    getAllMessageInfo({
+        params: {
+        }
+    }).then(res => {
+        if (res.code == 0) {
+            let { unReadCountTotal = 0 } = res.data;
+            if (unReadCountTotal > 0) {
+                let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal + '';
+                setBadgeInfo({ data: { text } });
             } else {
                 hideBadge();
             }

+ 19 - 1
src/view/iframe/buy-nft/buy/home.vue

@@ -113,6 +113,7 @@ import BtnLoading from '../components/btn-loading.vue'
 import Report from "@/log-center/log"
 import { getQueryString } from "@/uilts/help";
 import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
+let postId = inject('post_Id');
 let pay_info = inject('pay_info');
 let router = useRouter()
 let showDesc = ref(true)
@@ -155,6 +156,16 @@ const clickClose = () => {
 const clickJump = (item) => {
     pay_info.home.sale_plan = item
     router.push({ path: '/pay' });
+    // report
+    Report.reportLog({
+        pageSource: Report.pageSource.nftShopPage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.buy_button,
+        nftProjectId: projectId.value,
+        postEditorPostId: postId.value,
+    }, {
+        'buy-number': item.itemCount
+    })
 }
 
 const setDialogStyle = () => {
@@ -192,6 +203,7 @@ const redeemPost = () => {
                 businessType: Report.businessType.buttonClick,
                 objectType: Report.objectType.redeem_button,
                 nftProjectId: projectId.value,
+                postEditorPostId: postId.value,
             }, {
                 result: 'success'
             })
@@ -233,6 +245,7 @@ const redeemPost = () => {
                 businessType: Report.businessType.buttonClick,
                 objectType: Report.objectType.redeem_button,
                 nftProjectId: projectId.value,
+                postEditorPostId: postId.value,
             }, {
                 result: 'fail'
             })
@@ -257,6 +270,7 @@ const showRedeemLayer = () => {
         businessType: Report.businessType.buttonClick,
         objectType: Report.objectType.redeem_button,
         nftProjectId: projectId.value,
+        postEditorPostId: postId.value,
     })
 }
 
@@ -280,6 +294,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){
         pay_info.nft_group_Id = nft_group_Id
     }
@@ -290,6 +305,7 @@ onMounted(() => {
     // 作用域外用
     groupId.value = nft_group_Id
     projectId.value = nft_project_Id
+    postId.value = post_id
 
     getNftMysteryBoxSaleInfo({
         params: {
@@ -315,7 +331,8 @@ onMounted(() => {
     Report.reportLog({
         pageSource: Report.pageSource.nftShopPage,
         businessType: Report.businessType.pageView,
-        nftProjectId: nft_project_Id
+        nftProjectId: nft_project_Id,
+        postEditorPostId: postId.value,
     })
 })
 </script>
@@ -487,6 +504,7 @@ onMounted(() => {
                 border-radius: 100px;
                 color: #1D9BF0;
                 min-width: 110px;
+                min-height: 50px;
                 display: flex;
                 justify-content: center;
                 align-items: center;

+ 12 - 0
src/view/iframe/buy-nft/buy/open-box.vue

@@ -25,6 +25,7 @@
 import { reactive, onMounted, inject } from 'vue'
 import nftCard from "@/view/components/nft-card.vue"
 import router from "@/router/buy-nft.js";
+let postId = inject('post_Id')
 let pay_info = inject('pay_info');
 let state = reactive({
     box: {
@@ -68,6 +69,17 @@ const showNFTs = () => {
                         showJoinGroupFinish: state.showJoinGroupFinish
                     }
                 }, (res) => { });
+                // postId
+                if (postId.value) {
+                    chrome.tabs.getCurrent((tab) => {
+                        chrome.tabs.sendMessage(tab.id, {
+                            actionType: "FINISH_ToolBox_By_Nft",
+                            data: {
+                                post_Id: postId.value,
+                            }
+                        }, (res) => { });
+                    })
+                }
                 router.replace('/')
             })
         }

+ 37 - 0
src/view/iframe/buy-nft/buy/pay.vue

@@ -85,6 +85,7 @@
     </div>
 </template>
 <script setup >
+import Report from "@/log-center/log"
 import router from "@/router/buy-nft.js";
 import { ref, onMounted, inject, reactive } from 'vue'
 import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
@@ -98,6 +99,7 @@ import "element-plus/es/components/message/style/css";
 import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
 
 let pay_info = inject('pay_info');
+let postId = inject('post_Id');
 let state = reactive({
     loading: {
         show: false
@@ -138,6 +140,16 @@ const clickPlay = () => {
             pay_info.buy_items = res.data.buyItems
             sendChromeTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
             router.push({ path: '/open_box' });
+            Report.reportLog({
+                pageSource: Report.pageSource.nftShopPage,
+                businessType: Report.businessType.buttonClick,
+                objectType: Report.objectType.buy_button,
+                nftProjectId: pay_info.home.nftProjectId,
+                postEditorPostId: postId.value,
+            }, {
+                'buy-number': pay_info.home?.sale_plan?.itemCount,
+                result: 'success'
+            })
         } else {
             let msg = ''
             switch (res.code.toString()) {
@@ -166,10 +178,28 @@ const clickPlay = () => {
                 offset: -16,
                 appendTo: document.body
             })
+            Report.reportLog({
+                pageSource: Report.pageSource.nftShopPage,
+                businessType: Report.businessType.buttonClick,
+                objectType: Report.objectType.buy_button,
+                nftProjectId: pay_info.home.nftProjectId,
+                postEditorPostId: postId.value,
+            }, {
+                'buy-number': pay_info.home?.sale_plan?.itemCount,
+                result: 'fail'
+            })
         }
     }).catch(() => {
         state.loading.show = false
     })
+    // report
+    Report.reportLog({
+        pageSource: Report.pageSource.nftPreviewPage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.confirmButton,
+        nftProjectId: pay_info.home.nftProjectId,
+        postEditorPostId: postId.value,
+    })
 }
 // 余额是否同步中
 let asyncIng = ref(false);
@@ -213,6 +243,13 @@ onMounted(() => {
     currentCurrencyInfo.currencyCode = pay_info.home.sale_plan.currencyCode
     getLocalCurrencyInfoByCode();
     setDialogStyle()
+    // report
+    Report.reportLog({
+        pageSource: Report.pageSource.nftPreviewPage,
+        businessType: Report.businessType.pageView,
+        nftProjectId: pay_info.home.nftProjectId,
+        postEditorPostId: postId.value,
+    })
 })
 
 

+ 3 - 1
src/view/iframe/buy-nft/index.vue

@@ -4,9 +4,11 @@
     </div>
 </template>
 <script setup>
-import { reactive, provide } from 'vue'
+import { ref, reactive, provide } from 'vue'
 let pay_info = reactive({})
+let post_Id = ref('')
 provide('pay_info', pay_info)
+provide('post_Id', post_Id)
 let state = reactive({
     // 
     show: 'dialog-home'

+ 17 - 2
src/view/iframe/nft/card.vue

@@ -11,7 +11,13 @@
                     <img :src=" require('@/assets/img/icon-ntf-share.png') " />
                 </div>
             </div>
-            <div class="content">
+            <div
+                class="content"
+                v-show-log="{
+                    pageSource: isShare ? Report.pageSource.nft_post_page : Report.pageSource.nft_sales_window,
+                    nftProjectId: nftProjectId,
+                    redPacketType: Report.redPacketType.nftSale,
+                }">
                 <img :src="saleData.windowImagePath" />
             </div>
             <div
@@ -23,7 +29,13 @@
             <div
                 v-else
                 class="buy"
-                @click="buy">
+                @click="buy"
+                v-click-log="{
+                    pageSource: isShare ? Report.pageSource.nft_post_page : Report.pageSource.nft_sales_window,
+                    objectType: Report.objectType.buy_nft_button,
+                    nftProjectId: nftProjectId,
+                    redPacketType: Report.redPacketType.nftSale,
+                }">
                 <img class="guide" v-if="isShowGuide" :src=" require('@/assets/img/icon-arrow.png') " />
                 <button>Buy NFT</button>
             </div>
@@ -32,6 +44,7 @@
 </template>
 
 <script setup>
+import Report from "@/log-center/log"
 import { onBeforeMount, ref, onMounted, onBeforeUnmount } from 'vue'
 import { getTwitterSaleNftProjectInfo, getNftProjectInfo } from '@/http/nft'
 import { pageUrl } from "@/http/configAPI.js"
@@ -40,6 +53,7 @@ const saleData = ref({});
 const isShare = ref(false);
 const isLoading = ref(true);
 const isShowGuide = ref(false);
+const nftProjectId = ref('');
 
 const getSaleInfo = () => {
     chrome.tabs.getCurrent((tab) => {
@@ -152,6 +166,7 @@ onBeforeMount(() => {
     let projectId = searchParmas.get('projectId') || '';
     if (projectId) {
         isShare.value = true;
+        nftProjectId.value = projectId;
         getSaleData(projectId)
     } else {
         getSaleInfo()

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

@@ -0,0 +1,182 @@
+<template>
+    <div class="setting">
+        <a-radio-group v-model:value="type" name="radioType" @change="changeType">
+            <label class="item">
+                <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>
+                </div>
+            </label>
+            <label class="item">
+                <div class="sel"><a-radio value="nft"></a-radio></div>
+                <div class="inp">
+                    <img :src=" require('@/assets/svg/icon-post-edit-luck.svg') " />
+                    <span>NFT holders only</span>
+                </div>
+            </label>
+        </a-radio-group>
+        <div
+            v-if="showList"
+            ref="nftScroll"
+            class="scroll"
+            @scroll="getMore">
+            <div ref="nftGroupList">
+                <a-radio-group v-model:value="nftSelectId" name="radioList" @change="changeList">
+                    <label
+                        class="item"
+                        :key="index"
+                        v-for="(item, index) in nftList">
+                        <div class="sel2"></div>
+                        <div class="sel2"><a-radio :value="item.nftProjectId"></a-radio></div>
+                        <div class="inp">
+                            <img :src=" item.icon " />
+                            <span>{{ item.nftProjectName }}</span>
+                        </div>
+                    </label>
+                </a-radio-group>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onBeforeMount, onMounted, defineEmits } from "vue";
+import { ElMessage } from 'element-plus'
+import { listPossessNftProject } from "@/http/nft.js";
+import { throttle } from "@/uilts/help";
+
+let type = ref('public');
+let showList = ref(false);
+let nftSelectId = ref('');
+let nftList = ref([]);
+let pageSize = 100;
+let pageNum  = ref(1);
+let nftScroll = ref();
+let nftGroupList = ref();
+let getMoreStatus = ref(true);
+let emits = defineEmits(['change']);
+
+const changeType = (e) => {
+    if (e.target.value === 'nft' && nftList.value.length === 0) {
+        type.value = 'public';
+        showList.value = false;
+        ElMessage({
+            message: `Oops,only NFT holders can choose`,
+            type: 'warning',
+        })
+        emits('change', '');
+    } else if (e.target.value === 'nft' && nftList.value.length > 0) {
+        showList.value = true;
+        emits('change', nftSelectId.value);
+    } else if (e.target.value === 'public') {
+        showList.value = false;
+        emits('change', '');
+    }
+}
+const changeList = (e) => {
+    emits('change', e.target.value);
+}
+const getNftList = () => {
+    listPossessNftProject({
+        params: {
+            pageNum: pageNum.value,
+            pageSize: pageSize
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if ( code === 0 && data.length > 0 ) {
+            if (pageNum.value === 1) {
+                nftList.value = data;
+                nftSelectId.value = data[0]['nftProjectId'];
+            } else {
+                nftList.value = [...nftList.value, ...data];
+            }
+        }
+
+        if (data.length < pageSize) {
+            getMoreStatus.value = false
+        } else {
+            getMoreStatus.value = true
+        }
+    })
+}
+const getMore = throttle((e) => {
+    let oT = e.target.scrollTop;
+    let oH = nftGroupList.value.offsetHeight;
+    let sH = nftScroll.value.offsetHeight;
+
+    if ((oT + sH  >= oH - 20) && getMoreStatus.value) {
+        pageNum.value++
+        getNftList()
+    }
+}, 700)
+
+onBeforeMount(() => {
+    // get list
+    getNftList()
+})
+
+onMounted(() => {
+    emits('change', '');
+})
+</script>
+
+<style scoped lang="scss">
+.setting {
+    overflow: hidden;
+    clear: both;
+    height: calc(100% - 30px);
+    max-height: 600px;
+    border-radius: 12px;
+    background: #FFFFFF;
+    border: 1px solid #E6E6E6;
+    .item {
+        display: flex;
+        height: 52px;
+        cursor: pointer;
+        align-items: center;
+        .sel {
+            width: 52px;
+            text-align: center;
+            .ant-radio-wrapper {
+                margin-right: 0;
+            }
+        }
+        .sel2 {
+            width: 40px;
+            text-align: center;
+            .ant-radio-wrapper {
+                margin-right: 0;
+            }
+        }
+        .inp {
+            flex: 1;
+            display: flex;
+            align-items: center;
+            height: 52px;
+            background: #FFFFFF;
+            box-shadow: inset 0px -1px 0px #EFEFEF;
+            img {
+                width: 24px;
+                height: 24px;
+                margin-right: 12px;
+                border-radius: 2px;
+            }
+        }
+        &:last-child {
+            .inp {
+                box-shadow: unset;
+            }
+        }
+    }
+    .scroll {
+        overflow-y: auto;
+        height: calc(100% - 105px);
+    }
+}
+
+.ant-radio-group {
+    display: block;
+}
+</style>

+ 17 - 4
src/view/iframe/publish/components/select-publish-content.vue

@@ -1,6 +1,11 @@
 <template>
     <div class="overlay" v-if="visible">
-        <div class="content">
+        <div
+            class="content"
+            v-show-log="{
+                businessType: Report.businessType.pageView,
+                pageSource: Report.pageSource.main_page_dashboard,
+            }">
             <!-- 头部 -->
             <div class="head">
                 <div class="left">
@@ -19,7 +24,12 @@
                 <div v-for="(item, index) in list"
                     :key="index"
                     class="item"
-                    @click="clickItem(item, index)">
+                    @click="clickItem(item, index)"
+                    v-click-log="{
+                        businessType: Report.businessType.buttonClick,
+                        pageSource: Report.pageSource.main_page_dashboard,
+                        objectType: item.btnType
+                    }">
                     <img :src="item.icon" alt="">
                     {{item.txt}}
                 </div>
@@ -29,17 +39,20 @@
 </template>
 
 <script setup>
+import Report from "@/log-center/log"
 import { ref, watch, reactive, defineProps, onMounted } from "vue";
 let list = reactive([
     {
         icon: require('@/assets/svg/img-select-giveaway.svg'),
         type: 'REDPACKET',
-        txt: 'Giveaway'
+        txt: 'Giveaway',
+        btnType: 'giveaway-button',
     },
     {
         icon: require('@/assets/svg/img-select-tool-box.svg'),
         type: 'TOOL_BOX',
-        txt: 'Tool Box'
+        txt: 'Tool Box',
+        btnType: 'toolbox-button',
     }
 ])
 

+ 43 - 3
src/view/iframe/publish/tool-box/child/editor.vue

@@ -52,6 +52,7 @@
 <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 { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
@@ -80,6 +81,14 @@ const searchHandler = async (_params) => {
   let siteTitle = '', favicon = '';
   let timer = null;
 
+  // report
+  Report.reportLog({
+    pageSource: Report.pageSource.publisherDialog,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.custom_link_button,
+  }, {
+    type: 3
+  });
 
   if (!siteUrl.value) {
     return;
@@ -184,14 +193,23 @@ const getTitleByHtmlStr = (str = '') => {
 
 const clickHistoryAppHandler =  debounce(function(params) {
   if (params.appId) {
-    clickAppHandler(params);
+    clickAppHandler(params, false);
   } else {
     siteUrl.value = params.defaultUrl;
     searchHandler(params);
   }
+
+  Report.reportLog({
+    pageSource: Report.pageSource.publisherDialog,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.history_button,
+  }, {
+    appId: params && params.appId || '',
+    type: 3
+  });
 }, 800);
 
-const clickAppHandler =  debounce(function(params) {
+const clickAppHandler =  debounce(function(params, isReport = true) {
   let { createType, defaultUrl, appId, linkImagePath } = params;
   switch (createType) {
     case 1:
@@ -201,6 +219,17 @@ const clickAppHandler =  debounce(function(params) {
       openWindow(params);
       break;
   }
+
+  if (isReport) {
+    Report.reportLog({
+      pageSource: Report.pageSource.publisherDialog,
+      businessType: Report.businessType.buttonClick,
+      objectType: Report.objectType.app_button,
+    }, {
+      appId: appId || '',
+      type: 3
+    });
+  }
 }, 800);
 
 const openWindow = (params) => {
@@ -246,7 +275,18 @@ const createGuideWindow = (params, isUpdate = false) => {
     openWindowList.push(window2);
 
     setChromeStorage({ guideAppWindowList: JSON.stringify({list: openWindowList})});
-  })  
+
+    // report
+    Report.reportLog({
+      pageSource: Report.pageSource.post_editor_guide_page_left,
+      businessType: Report.businessType.pageView,
+    });
+
+    Report.reportLog({
+      pageSource: Report.pageSource.post_editor_guide_page_right,
+      businessType: Report.businessType.pageView,
+    });
+  })
 }
 
 const getAppList = () => {

+ 8 - 0
src/view/iframe/publish/tool-box/child/guide.vue

@@ -27,6 +27,7 @@
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { checkURL } from "@/uilts/help"
+import Report from "@/log-center/log"
 import { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
 import { message } from "ant-design-vue";
 
@@ -42,6 +43,13 @@ let pageData = reactive({
 const confirm = async () => {
     siteUrl.value = siteUrl.value.trim();
 
+    // report
+    Report.reportLog({
+      pageSource: Report.pageSource.post_editor_guide_page_right,
+      businessType: Report.businessType.buttonClick,
+      objectType: Report.objectType.enter_url_button,
+    });
+
     if (!checkURL(siteUrl.value)) {
         message.info('Incorrect URL entered');
         return;

+ 37 - 23
src/view/iframe/publish/tool-box/child/preview.vue

@@ -2,6 +2,9 @@
     <div class="editor-preview-wrapper">
         <div class="top">
             <div class="card-container">
+                <div class="font">
+                    Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
+                </div>
                 <!-- 安装之后的卡片样式 -->
                 <div class="content-after" v-show="installStatus" :style="{ 'width': reviewCanvasParams.width + 'px' }">
                     <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
@@ -37,7 +40,7 @@
                     <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
                         <img class="cover" v-if="previewData.linkImagePath && previewData.appId"
                             :src="previewData.linkImagePath" />
-                        <iframe class="iframe" sandbox :src="previewData.convertUrl" scrolling="no" v-else></iframe>
+                        <iframe class="iframe" :src="previewData.convertUrl" scrolling="no" v-else></iframe>
 
                         <div class="bottom-bar">
                             <div class="site-url">DeNet.me</div>
@@ -55,8 +58,9 @@
                     </div>
                 </div>
             </div>
-            <div class="font">
-                Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
+            <div class="setting">
+                <div class="font">Settings</div>
+                <slot></slot>
             </div>
         </div>
         <div class="bottom">
@@ -115,13 +119,17 @@ const props = defineProps({
     showCom: {
         type: String,
         default: 'EDITOR'
+    },
+    certNftProjectId: {
+        type: String,
+        default: ''
     }
 })
 
 watch(() => props.screenshotWebsiteData,
     (newVal) => {
         let { appId } = props.previewData;
-        if (loadingHide && (!appId || appId && !props.previewData.linkImagePath ) && (newVal.url || newVal.status)) {
+        if (loadingHide && (!appId || appId && !props.previewData.linkImagePath) && (newVal.url || newVal.status)) {
             loadingHide();
             loadingHide = null;
             submitPublish();
@@ -169,13 +177,13 @@ const getUserName = (screenName) => {
 const calcPreviewCanvasParams = () => {
     nextTick(() => {
         let containerDom = document.querySelector('.card-container');
-        let domHeight = containerDom && containerDom.offsetHeight || 500;
+        let domHeight = containerDom && containerDom.offsetHeight || 490;
         const canvasHeight = 780, canvasWidth = 620;
         if (domHeight < canvasHeight) {
             //比例: 高 / 宽
             let hWRatio = canvasHeight / canvasWidth;
             //缩小宽度 = 高度 / 比例
-            let width = domHeight / hWRatio;
+            let width = canvasWidth / hWRatio;
             if (width > canvasWidth) {
                 width = canvasWidth;
             }
@@ -198,7 +206,6 @@ const publishHandler = () => {
     if (loadingHide) {
         return;
     }
-
     if ((!appId || appId && !props.previewData.linkImagePath) && (!props.screenshotWebsiteData.url && !props.screenshotWebsiteData.status)) {
         loadingHide = message.loading('loading...', 0);
         return;
@@ -225,6 +232,9 @@ const submitPublish = () => {
         linkTitle: !appId ? linkTitle : '',
         linkImagePath: props.screenshotWebsiteData.url
     };
+    if (props.certNftProjectId !== '') {
+        postBizData['certNftProjectId'] = props.certNftProjectId;
+    }
     let data = {
         params: {
             postBizData: JSON.stringify(postBizData),
@@ -314,15 +324,13 @@ onUnmounted(() => {
         width: 100%;
         height: calc(100% - 80px);
         display: flex;
-        align-items: center;
-        justify-content: center;
-        overflow-y: auto;
-        padding: 20px 0;
+        justify-content: space-between;
+        padding: 20px 40px;
         box-sizing: border-box;
 
         .card-container {
             height: 100%;
-            margin-right: 50px;
+            margin-right: 32px;
 
             .content-after,
             .content-before {
@@ -366,10 +374,11 @@ onUnmounted(() => {
             .content-after {
                 background: url('@/assets/img/img-tool-box-preview-after.png');
                 width: 387px;
-                height: 100%;
-                background-size: contain;
+                height: calc(100% - 30px);
+                overflow: hidden;
+                background-size: cover;
                 background-repeat: no-repeat;
-                border: 1px solid #D1D9DD;
+                border: 1px solid #E6E6E6;
                 border-radius: 13px;
                 box-sizing: border-box;
 
@@ -388,24 +397,25 @@ onUnmounted(() => {
 
             .content-before {
                 background: url('@/assets/img/img-tool-box-preview-before.png');
-                background-size: contain;
+                background-size: cover;
                 background-repeat: no-repeat;
-                height: 100%;
-                border: 1px solid #D1D9DD;
+                height: calc(100% - 30px);
+                overflow: hidden;
+                border: 1px solid #E6E6E6;
                 border-radius: 13px;
                 box-sizing: border-box;
 
                 .card-wrapper {
-                    width: 505px;
-                    height: 338px;
-                    border: 1px solid #D1D9DD;
+                    width: 448px;
+                    height: 300px;
+                    border: 1px solid #E6E6E6;
                     background: #ffffff;
                     box-sizing: border-box;
                     overflow: hidden;
                     position: relative;
                     box-sizing: border-box;
                     border-radius: 16px;
-                    left: 73px;
+                    left: 70px;
                     top: 90px;
 
                     .iframe {
@@ -446,7 +456,7 @@ onUnmounted(() => {
         }
 
         .font {
-            width: 300px;
+            height: 30px;
             font-weight: 600;
             font-size: 20px;
 
@@ -454,6 +464,10 @@ onUnmounted(() => {
                 color: #1D9BF0;
             }
         }
+
+        .setting {
+            flex: 1;
+        }
     }
 
     .bottom {

+ 10 - 1
src/view/iframe/publish/tool-box/index.vue

@@ -6,7 +6,10 @@
             :screenshotWebsiteData="screenshotWebsiteData"
             :showCom="showCom"
             :defaultLinkTitle="pageData.defaultLinkTitle"
-            @publishFinish="publishFinish" />
+            :certNftProjectId="certNftProjectId"
+            @publishFinish="publishFinish">
+            <nft-setting @change="changeSetting"></nft-setting>
+        </preview>
     </div>
 </template>
 
@@ -17,6 +20,7 @@ import { screenshotWebsite } 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"
+import nftSetting from '@/view/iframe/publish/components/nft-setting.vue'
 
 const props = defineProps({
     pageData: {
@@ -60,6 +64,7 @@ let previewData = reactive({
     appId: '',
     currentApp: {}
 })
+let certNftProjectId = ref('')
 
 let screenshotWebsiteData = reactive({
     url: '',
@@ -106,6 +111,10 @@ const publishFinish = (params) => {
     emits("toolBoxPublishFinish", params);
 }
 
+const changeSetting = (id = '') => {
+    certNftProjectId.value = id;
+}
+
 </script>
 
 <style lang="scss" scoped>

+ 198 - 0
src/view/iframe/tool-box/buy-nft.vue

@@ -0,0 +1,198 @@
+<template>
+    <div
+        class="nft-layer"
+        v-show-log="{
+            pageSource: Report.pageSource.buy_posteditor_nft_dialog,
+        }">
+        <div class="title">
+            <img @click="close" :src=" require('@/assets/svg/icon-close.svg') " />
+            <span class="text">Unlock by Ruomeng 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>
+            </div>
+            <div
+                class="btn"
+                v-if="btnStatus"
+                @click="buy"
+                v-click-log="{
+                    pageSource: Report.pageSource.buy_posteditor_nft_dialog,
+                    objectType: Report.objectType.buy_button,
+                }">
+                <span>Buy NFT to Participate</span>
+            </div>
+            <div class="btn disabled" v-else>
+                <span>Buy NFT to Participate</span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import Report from "@/log-center/log"
+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 "element-plus/es/components/message/style/css";
+
+const postId = ref('')
+const btnStatus = ref(false)
+const nftAuthINfo = ref(null)
+
+const close = () => {
+    sendChromeTabMessage({
+        actionType: 'Hide_ToolBox_By_Nft'
+    })
+}
+
+const buy = () => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            if (nftAuthINfo.value && nftAuthINfo.value?.publishStatus === 1) {
+                chrome.tabs.getCurrent((tab) => {
+                    chrome.tabs.sendMessage(tab.id, {
+                        actionType: "IFRAME_TWITTER_SHOW_BUY_NFT",
+                        data: {
+                            nft_project_Id: nftAuthINfo.value.certNftProjectId,
+                            post_Id: postId.value,
+                        }
+                    }, (res) => { });
+                })
+                // close buy
+                close();
+            } else {
+                ElMessage({
+                    message: `NFT project not published!`,
+                    type: 'error',
+                })
+            }
+        }
+    })
+}
+
+onBeforeMount(() => {
+    postId.value = getQueryString('postId')
+    getPostEditorNftCertInfo({
+        params: {
+            postId: postId.value
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if ( code === 0 ) {
+            btnStatus.value = true;
+            nftAuthINfo.value = data;
+        }
+    })
+})
+
+</script>
+
+<style lang="scss">
+body {
+    margin: 0;
+    padding: 0;
+}
+.nft-layer {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    width: 500px;
+    height: 420px;
+    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;
+            margin-left: 14px;
+            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;
+            font-weight: 400;
+            text-align: center;
+            line-height: 33px;
+            margin: auto;
+            margin-bottom: 28px;
+            width: calc(100% - 30px);
+            &::before {
+                position: absolute;
+                top: 50%;
+                left: 0;
+                content: '';
+                display: block;
+                width: 14%;
+                height: 1px;
+                background-color: rgba($color: #000000, $alpha: .2);
+            }
+            &::after {
+                position: absolute;
+                top: 50%;
+                right: 0;
+                content: '';
+                display: block;
+                width: 14%;
+                height: 1px;
+                background-color: rgba($color: #000000, $alpha: .2);
+            }
+        }
+        .btn {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin: auto;
+            width: calc(100% - 30px);
+            height: 46px;
+            color: #FFFFFF;
+            cursor: pointer;
+            font-size: 16px;
+            font-weight: 600;
+            border-radius: 100px;
+            background: #1D9BF0;
+            &.disabled {
+                background: #CDCDCD;
+                cursor: not-allowed;
+                color: #fff;
+            }
+        }
+    }
+}
+</style>

+ 325 - 20
src/view/iframe/tool-box/card.vue

@@ -11,6 +11,16 @@
             <iframe :src="iframe_url" frameborder="0" sandbox></iframe>
         </div>
         <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') " />
+                    <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>
+                    </div>
+                </div>
+                <img class="mask_bg" v-if="state.detail.linkImagePath" :src=" state.detail.linkImagePath " />
+            </template>
             <iframe :src="state.iframe_url" v-show="state.status == 'iframe'" ref="dom_iframe" frameborder="0"
                 scrolling="yes" allow="camera *;microphone *"></iframe>
             <!-- sandbox="allow-same-origin allow-scripts allow-popups allow-top-navigation allow-forms allow-modals allow-popups-to-escape-sandbox" -->
@@ -64,9 +74,13 @@
 <script setup>
 import { getChromeStorage, setChromeStorage, defineProps, sendChromeTabMessage } from "@/uilts/chromeExtension";
 import { getPostDetail } from '@/http/redPacket.js'
+import { getPostEditorNftCertInfo } from '@/http/toolBoxApi'
 import { guid, getQueryString } from "@/uilts/help";
-import { onMounted, reactive, ref } from "vue";
+import { onMounted, reactive, ref, onBeforeUnmount } from "vue";
+import { ElMessage } from 'element-plus'
 import { reSetBindTwtterId } from '@/http/help.js'
+import Report from "@/log-center/log"
+import "element-plus/es/components/message/style/css";
 let dom_iframe = ref(null)
 let state = reactive({
     status: '', //
@@ -79,10 +93,13 @@ let state = reactive({
     tweetId: '',
     detail: {},
     handle_type: '',
+    showMask: false,
     cover_url: require('@/assets/img/back-loading.png')
 })
 
 let dom = {}
+let nftAuthINfo = ref(null)
+let loadTime = (new Date).getTime()
 
 let props = defineProps({
     pre_view: {
@@ -103,6 +120,10 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
                 state.show_btn = true
                 state.status = 'iframe'
                 state.iframe_url = req.data.iframe_url
+                nftAuthINfo.value = req.data.nftAuthINfo
+                state.showMask = req.data.showMask
+                state.detail = req.data.detail
+                state.postId = req.data.postId
             }
             break
     }
@@ -139,6 +160,19 @@ onMounted(() => {
         }
     })
 
+    chrome.runtime.onMessage.addListener(msgListener)
+
+    // 页面返回重试状态
+    document.addEventListener('visibilitychange', function () {
+        let isHidden = document.hidden;
+        if (!isHidden && !nftAuthINfo.value) {
+            getDetail();
+        }
+    });
+})
+
+onBeforeUnmount(() => {
+    chrome.runtime.onMessage.removeListener(msgListener);
 })
 
 // detail函数
@@ -148,6 +182,7 @@ const getDetail = () => {
         state.status = '网页错误'
     }
     // iframe.onload = () => {
+    //     alert(123)
     //     if (state.status == '加载' || state.status == 'iframe') {
     //         state.show_btn = true
     //         state.status = 'iframe'
@@ -172,29 +207,199 @@ const getDetail = () => {
             if (state.detail.viewBgImagePath) {
                 state.cover_url = state.detail.viewBgImagePath
             }
+            state.iframe_url = state.detail.convertUrl
             state.show_btn = true
             state.status = 'iframe'
-            state.iframe_url = state.detail.convertUrl
+            // 蒙层
+            if (state.detail && state.detail.certNftProjectId) {
+                state.showMask = true;
+                // 确权
+                getChromeStorage('userInfo', (_userInfo) => {
+                    if (_userInfo) {
+                        getNftInfoStatus()
+                    }
+                })
+            } else {
+                reportSucc(false)
+            }
+            // report
+            Report.reportLog({
+                redPacketType: Report.redPacketType.postEditor,
+                businessType: Report.businessType.pageView,
+                pageSource: Report.pageSource.pe_loading_page,
+                postId: state.postId || '',
+                postEditorUrl: state.detail.convertUrl
+            });
         } else {
             state.status = '网页错误'
         }
     })
 }
 
+const getNftInfoStatus = () => {
+    getPostEditorNftCertInfo({
+        params: {
+            postId: state.postId,
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if ( code === 0 ) {
+            nftAuthINfo.value = data;
+            // checkMask
+            getChromeStorage('post_id_list', (list) => {
+                if (list && list.indexOf(state.postId) !== -1 && nftAuthINfo.value?.certStatus === 1) {
+                    state.showMask = false;
+                    // report
+                    reportSucc()
+                } else {
+                    // report
+                    reportFail()
+                }
+            })
+        }
+    })
+}
+
+const reportSucc = (isEncrypted = true) => {
+    let params = {}
+    if (isEncrypted) {
+        params['nft-encrypted-status'] = 1;
+    }
+    // report
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.pageView,
+        pageSource: Report.pageSource.pe_display_page,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    }, {
+        'loading-time': (new Date).getTime() - loadTime,
+    });
+}
+
+const reportFail = () => {
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.pageView,
+        pageSource: Report.pageSource.pe_display_page,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        'nft-encrypted-status': 0,
+    }, {
+        'loading-time': (new Date).getTime() - loadTime,
+    });
+}
+
+const confirmStatus = () => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            if (nftAuthINfo.value && nftAuthINfo.value?.certStatus === 1) {
+                succBack()
+            } else {
+                sendChromeTabMessage({
+                    actionType: 'Set_ToolBox_By_Nft',
+                    data: {
+                        postId: state.postId,
+                    }
+                })
+            }
+        }
+    })
+
+    // report
+    let params = {}
+    if (nftAuthINfo.value?.certStatus === 1) {
+        if (state.showMask) {
+            params['nft-encrypted-status'] = 0
+        } else {
+            params['nft-encrypted-status'] = 1
+        }
+    }
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.buttonClick,
+        pageSource: Report.pageSource.pe_display_page,
+        objectType: Report.objectType.encrypte_nft_button,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    });
+}
+
+const succBack = () => {
+    ElMessage({
+        message: `NFT validated!`,
+        type: 'success'
+    })
+    state.showMask = false;
+    // 记录解锁
+    getChromeStorage('post_id_list', (list) => {
+        let originList = list ? list : [];
+        if (originList.indexOf(state.postId) === -1) {
+            originList.push(state.postId)
+            setChromeStorage({ post_id_list: JSON.stringify(originList) })
+        }
+    })
+}
+
+const hideMask = (data) => {
+    if (data && data.post_Id && data.post_Id === state.postId) {
+        succBack()
+    }
+}
+
 const clickCancel = () => {
     state.show_alert = false
 }
 
 const clickFixed = () => {
-    state.handle_type = '固定右上角'
-    getChromeStorage('fullCheck', (res) => {
-        if (res && res.fullCheck) {
-            // 固定
-            handleFixed()
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
         } else {
-            state.show_alert = true
+            state.handle_type = '固定右上角'
+            getChromeStorage('fullCheck', (res) => {
+                if (res && res.fullCheck) {
+                    // 固定
+                    handleFixed()
+                } else {
+                    state.show_alert = true
+                }
+            })
         }
     })
+
+    // report
+    let params = {}
+    if (nftAuthINfo.value?.certStatus === 1) {
+        if (state.showMask) {
+            params['nft-encrypted-status'] = 0
+        } else {
+            params['nft-encrypted-status'] = 1
+        }
+    }
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.buttonClick,
+        pageSource: Report.pageSource.pe_display_page,
+        objectType: Report.objectType.top_right_button,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    });
 }
 
 // 固定
@@ -202,19 +407,34 @@ const handleFull = () => {
     if (state.status != 'iframe' || !state.iframe_url) {
         return
     }
-    // 切换状态
-    state.status = '固定右上角'
-    state.show_btn = false
-    sendChromeTabMessage({
-        actionType: 'Set_ToolBox_Fixed',
-        data: {
-            type: '全屏',
-            iframe_url: state.iframe_url,
-            tweetId: state.tweetId,
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            // 切换状态
+            state.status = '固定右上角'
+            state.show_btn = false
+            sendChromeTabMessage({
+                actionType: 'Set_ToolBox_Fixed',
+                data: {
+                    type: '全屏',
+                    iframe_url: state.iframe_url,
+                    tweetId: state.tweetId,
+                    nftAuthINfo: nftAuthINfo.value,
+                    showMask: state.showMask,
+                    detail: state.detail,
+                    postId: state.postId,
+                }
+            })
+            // 清除当前iframe src
+            state.iframe_url = ''
         }
     })
-    // 清除当前iframe src
-    state.iframe_url = ''
 }
 
 // 全屏
@@ -227,7 +447,11 @@ const handleFixed = () => {
         data: {
             type: '固定右上角',
             iframe_url: state.iframe_url,
-            tweetId: state.tweetId
+            tweetId: state.tweetId,
+            nftAuthINfo: nftAuthINfo.value,
+            showMask: state.showMask,
+            detail: state.detail,
+            postId: state.postId,
         }
     })
     // 清除当前iframe src
@@ -244,6 +468,35 @@ const clickFull = () => {
             state.show_alert = true
         }
     })
+    // report
+    let params = {}
+    if (nftAuthINfo.value?.certStatus === 1) {
+        if (state.showMask) {
+            params['nft-encrypted-status'] = 0
+        } else {
+            params['nft-encrypted-status'] = 1
+        }
+    }
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.buttonClick,
+        pageSource: Report.pageSource.pe_display_page,
+        objectType: Report.objectType.fullscreen_button,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    });
+}
+
+const msgListener = (req, sender, sendResponse) => {
+    switch (req.actionType) {
+        case 'BG_LOGIN_SET_USERINFO_CB':
+            getDetail()
+            break;
+        case 'FINISH_ToolBox_By_Nft':
+            hideMask(req.data)
+            break;
+    }
 }
 
 </script>
@@ -266,6 +519,7 @@ const clickFull = () => {
     .alert {
         text-align: center;
         position: absolute;
+        z-index: 3;
         top: 0;
         left: 0;
         width: 100%;
@@ -390,6 +644,7 @@ const clickFull = () => {
     }
 
     .content {
+        position: relative;
         width: 100%;
         height: calc(100% - 40px);
         background: #686868;
@@ -397,6 +652,56 @@ const clickFull = () => {
         align-items: center;
         justify-content: center;
 
+        .mask {
+            position: absolute;
+            z-index: 2;
+            display: flex;
+            cursor: pointer;
+            align-items: center;
+            justify-content: center;
+            flex-direction: column;
+            width: 100%;
+            height: 100%;
+            background-color: rgba($color: #000000, $alpha: .8);
+            .luck {
+                width: 100px;
+                height: 100px;
+            }
+            .btn {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                width: 345px;
+                height: 70px;
+                margin-top: 12px;
+                border-radius: 100px;
+                background: #1D9BF0;
+                .img {
+                    overflow: hidden;
+                    width: 35px;
+                    height: 35px;
+                    margin-right: 16px;
+                    border-radius: 4px;
+                }
+                .font {
+                    width: 188px;
+                    color: #fff;
+                    font-weight: 700;
+                    font-size: 16px;
+                    line-height: 19px;
+                    letter-spacing: 0.3px;
+                }
+            }
+        }
+        .mask_bg {
+            position: absolute;
+            z-index: 1;
+            width: 100%;
+            height: 100%;
+            object-fit: contain;
+            background-color: #000000;
+        }
+
         iframe {
             background: #fff;
             width: 100%;

+ 133 - 5
src/view/iframe/tool-box/full.vue

@@ -12,13 +12,25 @@
             </div>
         </div>
         <div class="content">
+            <template v-if="showMask">
+                <div class="mask" @click="confirmStatus">
+                    <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>
+                    </div>
+                </div>
+                <img class="mask_bg" v-if="detail.linkImagePath" :src=" detail.linkImagePath " />
+            </template>
             <iframe :src="state.iframe_url" frameborder="0" allow="camera *;microphone *"></iframe>
         </div>
     </div>
 </template>
 <script setup>
-import { reactive } from "vue";
-import { sendChromeTabMessage } from "@/uilts/chromeExtension";
+import { reactive, ref } from "vue";
+import { ElMessage } from 'element-plus'
+import { getChromeStorage, setChromeStorage, sendChromeTabMessage } from "@/uilts/chromeExtension";
+import "element-plus/es/components/message/style/css";
 
 let state = reactive({
     status: '固定右上角', // 全屏
@@ -26,13 +38,21 @@ let state = reactive({
     tweetId: ''
 })
 
-chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
+let detail = ref(null)
+let nftAuthINfo = ref(null)
+let showMask = ref(false)
+let postId = ref('')
 
+chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     switch (req.actionType) {
         // 事件传输
         case 'Set_ToolBox_Fixed':
             if (req.data.type == '全屏' || req.data.type == '固定右上角') {
                 state.status = req.data.type
+                nftAuthINfo.value = req.data.nftAuthINfo;
+                showMask.value = req.data.showMask;
+                detail.value = req.data.detail;
+                postId.value = req.data.postId;
                 if (state.tweetId != req.data.tweetId) {
                     state.tweetId = req.data.tweetId
                 }
@@ -40,8 +60,10 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
                     state.iframe_url = req.data.iframe_url
                 }
             }
-
             break
+        case 'FINISH_ToolBox_By_Nft':
+            hideMask(req.data)
+            break;
     }
 })
 
@@ -74,14 +96,18 @@ const changeFixed = () => {
             type: '固定右上角',
             iframe_url: state.iframe_url,
             tweetId: state.tweetId,
+            nftAuthINfo: nftAuthINfo.value,
+            showMask: showMask.value,
+            detail: detail.value,
+            postId: postId.value,
         }
     })
 }
 
 const clickClose = () => {
     sendClose()
-
 }
+
 const sendClose = () => {
     sendChromeTabMessage({
         actionType: 'Set_ToolBox_Fixed',
@@ -89,12 +115,61 @@ const sendClose = () => {
             type: '关闭',
             iframe_url: state.iframe_url,
             tweetId: state.tweetId,
+            nftAuthINfo: nftAuthINfo.value,
+            showMask: showMask.value,
+            detail: detail.value,
+            postId: postId.value,
         }
     })
     state.iframe_url = ''
     state.tweetId = ''
 }
 
+const confirmStatus = () => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            if (nftAuthINfo.value && nftAuthINfo.value?.certStatus === 1) {
+                succBack()
+            } else {
+                sendChromeTabMessage({
+                    actionType: 'Set_ToolBox_By_Nft',
+                    data: {
+                        postId: postId.value,
+                    }
+                })
+            }
+        }
+    })
+}
+
+const succBack = () => {
+    ElMessage({
+        message: `NFT validated!`,
+        type: 'success'
+    })
+    showMask.value = false;
+    // 记录解锁
+    getChromeStorage('post_id_list', (list) => {
+        let originList = list ? list : [];
+        if (originList.indexOf(postId.value) === -1) {
+            originList.push(postId.value)
+            setChromeStorage({ post_id_list: JSON.stringify(originList) })
+        }
+    })
+}
+
+const hideMask = (data) => {
+    if (data && data.post_Id && data.post_Id === postId.value) {
+        succBack()
+    }
+}
 
 </script>
 
@@ -144,6 +219,7 @@ const sendClose = () => {
     }
 
     .content {
+        position: relative;
         width: 100%;
         height: calc(100% - 40px);
         background: #686868;
@@ -151,6 +227,58 @@ const sendClose = () => {
         align-items: center;
         justify-content: center;
 
+        .mask {
+            position: absolute;
+            z-index: 2;
+            display: flex;
+            cursor: pointer;
+            align-items: center;
+            justify-content: center;
+            flex-direction: column;
+            width: 100%;
+            height: 100%;
+            background-color: rgba($color: #000000, $alpha: .8);
+            .luck {
+                width: 100px;
+                height: 100px;
+            }
+            .btn {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                width: 345px;
+                height: 70px;
+                cursor: pointer;
+                margin-top: 12px;
+                border-radius: 100px;
+                background: #1D9BF0;
+                .img {
+                    overflow: hidden;
+                    width: 35px;
+                    height: 35px;
+                    margin-right: 16px;
+                    border-radius: 4px;
+                }
+                .font {
+                    width: 188px;
+                    color: #fff;
+                    font-weight: 700;
+                    font-size: 16px;
+                    line-height: 19px;
+                    letter-spacing: 0.3px;
+                }
+            }
+        }
+
+        .mask_bg {
+            position: absolute;
+            z-index: 1;
+            width: 100%;
+            height: 100%;
+            object-fit: contain;
+            background-color: #000000;
+        }
+
         iframe {
             width: 100%;
             height: 100%;

+ 4 - 9
src/view/popup/tabbar-page/message/index.vue

@@ -28,15 +28,9 @@
                 </template>
                 <!-- 转出NFT记录 -->
                 <template v-else-if="item.type == 4">
-                  <img
-                    v-if="item.nftItemVO?.imagePath"
-                    class="icon-big-give"
-                    :src="item.nftItemVO?.imagePath" />
+                  <img v-if="item.nftItemVO?.imagePath" class="icon-big-give" :src="item.nftItemVO?.imagePath" />
                   <div v-else style="margin-top: 12px;">
-                    <nft-card
-                      :nftItemId="item.nftItemId"
-                      :item="item.nftItemVO.createImageInfo"
-                      :width="34">
+                    <nft-card :nftItemId="item.nftItemId" :item="item.nftItemVO.createImageInfo" :width="34">
                     </nft-card>
                   </div>
                 </template>
@@ -275,7 +269,8 @@
                     </div>
                   </div>
                   <!-- 发红包—— 未发出、进行中 隐藏 -->
-                  <img v-if="item.type != 2 && item.type != 4" class="icon" :src="require('@/assets/svg/icon-cell-arrow-right.svg')" />
+                  <img v-if="item.type != 2 && item.type != 4" class="icon"
+                    :src="require('@/assets/svg/icon-cell-arrow-right.svg')" />
                 </div>
               </div>
             </div>