card.vue 8.6 KB

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