card.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <template>
  2. <div class="nft" :class="{ border: isShare }">
  3. <template v-if="!isLoading">
  4. <div class="title">
  5. <div class="tag" :class="{ share: !isShare }">
  6. <img class="logo" :src="saleData.nftProjectAvatar" />
  7. <font class="text" :class="{ share: !isShare }">{{saleData.nftProjectName}}</font>
  8. <img class="tagImg" :src=" require('@/assets/img/icon-nft.png') " />
  9. </div>
  10. <div class="share" v-if="!isShare" @click="share">
  11. <img :src=" require('@/assets/img/icon-ntf-share.png') " />
  12. </div>
  13. </div>
  14. <div
  15. class="content"
  16. v-show-log="{
  17. pageSource: isShare ? Report.pageSource.nft_post_page : Report.pageSource.nft_sales_window,
  18. nftProjectId: nftProjectId,
  19. redPacketType: Report.redPacketType.nftSale,
  20. srcContentId: isShare ? tweetId : ''
  21. }">
  22. <img :src="saleData.windowImagePath" />
  23. </div>
  24. <div
  25. v-if="saleData.purchaseStatus === 0"
  26. class="buy disabled">
  27. <img class="guide" v-if="isShowGuide" :src=" require('@/assets/img/icon-arrow.png') " />
  28. <button>Buy NFT</button>
  29. </div>
  30. <div
  31. v-else
  32. class="buy"
  33. @click="buy"
  34. v-click-log="{
  35. pageSource: isShare ? Report.pageSource.nft_post_page : Report.pageSource.nft_sales_window,
  36. objectType: Report.objectType.buy_nft_button,
  37. nftProjectId: nftProjectId,
  38. redPacketType: Report.redPacketType.nftSale,
  39. srcContentId: isShare ? tweetId : ''
  40. }">
  41. <img class="guide" v-if="isShowGuide" :src=" require('@/assets/img/icon-arrow.png') " />
  42. <button>Buy NFT</button>
  43. </div>
  44. </template>
  45. </div>
  46. </template>
  47. <script setup>
  48. import Report from "@/log-center/log"
  49. import { onBeforeMount, ref, onMounted, onBeforeUnmount } from 'vue'
  50. import { getTwitterSaleNftProjectInfo, getNftProjectInfo } from '@/http/nft'
  51. import { pageUrl } from "@/http/configAPI.js"
  52. import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
  53. const saleData = ref({});
  54. const isShare = ref(false);
  55. const isLoading = ref(true);
  56. const isShowGuide = ref(false);
  57. const nftProjectId = ref('');
  58. let tweetId = ref('');
  59. const getSaleInfo = () => {
  60. chrome.tabs.getCurrent((tab) => {
  61. let url = new URL(tab.url);
  62. let pathname = url.pathname;
  63. let pathArr, account;
  64. if (pathname) {
  65. pathname = decodeURIComponent(pathname);
  66. pathname = pathname.slice(1);
  67. pathArr = pathname.split('/');
  68. account = pathArr[0];
  69. getSaleProjectInfo(account);
  70. }
  71. })
  72. }
  73. const getSaleData = (projectId) => {
  74. getNftProjectInfo({
  75. params: {
  76. nftProjectId: projectId
  77. }
  78. }).then(res => {
  79. let { data } = res;
  80. if (data !== null) {
  81. // setData
  82. saleData.value = data;
  83. isLoading.value = false;
  84. }
  85. })
  86. }
  87. const getSaleProjectInfo = (account) => {
  88. getTwitterSaleNftProjectInfo({
  89. params: {
  90. twitterAccount: account
  91. }
  92. }).then(res => {
  93. let { data } = res;
  94. if (data !== null) {
  95. // setData
  96. saleData.value = data;
  97. isLoading.value = false;
  98. // postMessage
  99. chrome.tabs.getCurrent((tab) => {
  100. chrome.tabs.sendMessage(tab.id, { actionType: "IFRAME_NFT_SHOW_SALE" });
  101. })
  102. getChromeStorage('nft_guide', (info) => {
  103. if (!info) {
  104. isShowGuide.value = true
  105. setTimeout(() => {
  106. setChromeStorage({ nft_guide: Date.now() })
  107. }, 2000)
  108. }
  109. })
  110. }
  111. })
  112. }
  113. const share = () => {
  114. chrome.tabs.getCurrent((tab) => {
  115. let tagUrl = new URL(tab.url);
  116. let tagPathName = tagUrl.pathname.slice(1);
  117. let tagSearch = ``;
  118. if (tagPathName) {
  119. let tagArr = tagPathName.split('/');
  120. tagSearch = `${btoa(tagArr[0])}`
  121. }
  122. let url = pageUrl + `/nft/${saleData.value.nftProjectId}/${tagSearch}`
  123. let content = `#DNFT\r\r${url}`
  124. chrome.tabs.getCurrent((tab) => {
  125. chrome.tabs.sendMessage(tab.id, { actionType: "IFRAME_TWITTER_PUBLISH", publishRes: { srcContent: content } });
  126. });
  127. });
  128. }
  129. const buy = () => {
  130. getChromeStorage('userInfo', (_userInfo) => {
  131. if (!_userInfo) {
  132. setChromeStorage({ buyNFTCardData: JSON.stringify({ action: 'buy' })});
  133. chrome.runtime.sendMessage(
  134. { actionType: "POPUP_LOGIN", data: "" },
  135. (response) => {
  136. console.log("res", response);
  137. }
  138. )
  139. } else {
  140. chrome.tabs.getCurrent((tab) => {
  141. chrome.tabs.sendMessage(tab.id, {
  142. actionType: "IFRAME_TWITTER_SHOW_BUY_NFT",
  143. data: {
  144. nft_project_Id: saleData.value.nftProjectId
  145. }
  146. }, (res) => { });
  147. })
  148. }
  149. })
  150. }
  151. const loginSuccessHandler = async () => {
  152. let {action = ''} = await getChromeStorage('buyNFTCardData') || {};
  153. if(action == 'buy') {
  154. chrome.storage.local.remove("buyNFTCardData");
  155. buy();
  156. }
  157. }
  158. onBeforeMount(() => {
  159. let urlParams = new URL(window.location.href);
  160. let searchParmas = new URLSearchParams(urlParams.search);
  161. let projectId = searchParmas.get('projectId') || '';
  162. tweetId.value = searchParmas.get('tweetId') || '';
  163. if (projectId) {
  164. isShare.value = true;
  165. nftProjectId.value = projectId;
  166. getSaleData(projectId)
  167. } else {
  168. getSaleInfo()
  169. }
  170. })
  171. const onRuntimeMsg = () => {
  172. chrome.runtime.onMessage.addListener(msgListener)
  173. }
  174. const msgListener = (req, sender, sendResponse) => {
  175. switch (req.actionType) {
  176. case 'BG_LOGIN_SET_USERINFO_CB':
  177. loginSuccessHandler();
  178. break;
  179. }
  180. sendResponse && sendResponse();
  181. }
  182. onMounted(() => {
  183. onRuntimeMsg();
  184. })
  185. onBeforeUnmount(() => {
  186. chrome.runtime.onMessage.removeListener(msgListener);
  187. })
  188. </script>
  189. <style lang='scss'>
  190. body {
  191. margin: 0;
  192. padding: 0;
  193. }
  194. .nft {
  195. width: 100%;
  196. height: 290px;
  197. user-select:none;
  198. border-radius:20px;
  199. background:#F7F9F9;
  200. &.border {
  201. box-sizing: border-box;
  202. border: solid 1px #DCDCDC;
  203. }
  204. .title {
  205. height: 46px;
  206. display: flex;
  207. justify-content: space-between;
  208. align-items: center;
  209. .tag {
  210. display: flex;
  211. max-width: 93%;
  212. align-items: center;
  213. padding-left: 15px;
  214. &.share {
  215. max-width: 84%;
  216. }
  217. .logo {
  218. overflow: hidden;
  219. width: 20px;
  220. height: 20px;
  221. border-radius: 50%;
  222. background-color: #eee;
  223. }
  224. .text {
  225. font-size: 18px;
  226. font-weight: bold;
  227. max-width: calc(100% - 80px);
  228. margin: 0 7px;
  229. overflow: hidden;
  230. white-space: nowrap;
  231. text-overflow: ellipsis;
  232. &.share {
  233. max-width: calc(100% - 80px);
  234. }
  235. }
  236. .tagImg {
  237. width: 37px;
  238. height: 22px;
  239. }
  240. }
  241. .share {
  242. cursor: pointer;
  243. padding-right: 10px;
  244. img {
  245. width: 19px;
  246. height: 18px;
  247. }
  248. }
  249. }
  250. .content {
  251. height: 190px;
  252. img {
  253. width: 100%;
  254. height: 100%;
  255. }
  256. }
  257. .buy {
  258. position: relative;
  259. height: 54px;
  260. display: flex;
  261. justify-content: center;
  262. &.disabled {
  263. opacity: .1;
  264. }
  265. .guide {
  266. position: absolute;
  267. top: 6px;
  268. right: 30%;
  269. width: 26px;
  270. animation: fade 1s infinite;
  271. }
  272. button {
  273. width: 100%;
  274. height: 34px;
  275. margin: 0 20px;
  276. cursor: pointer;
  277. color: #ffffff;
  278. font-size: 15px;
  279. font-weight: bold;
  280. background: #000;
  281. border: 0;
  282. border-radius: 44px;
  283. }
  284. }
  285. }
  286. @keyframes fade {
  287. 0%, 100% {
  288. opacity: .5;
  289. transform: scale(1);
  290. }
  291. 50% {
  292. opacity: 1;
  293. transform: scale(1.4);
  294. }
  295. }
  296. </style>