invite-friends.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <template>
  2. <div class="invite-friends">
  3. <div class="invite-friends-content">
  4. <div class="invite-friends-content-head">
  5. <div class="title">Invite Friends to Open the Chest!</div>
  6. <div class="info">Invitees Need to be Real New follower of {{followUserStr}} to receive rewards</div>
  7. </div>
  8. <div class="invite-friends-content-body">
  9. <img class="tips" v-if="state.active_share_channel" :src="require('@/assets/svg/icon-channel-tips.svg')" />
  10. <div class="share-list" :class="{'share-list-active': state.active_share_channel}">
  11. <div v-for="(item, index) in state.share_list" :key="index" :data-clipboard-text="item.inviteContent"
  12. @click="clickShare(item)" class="share-item">
  13. <img :src="item.iconPath" />
  14. <div class="name">
  15. {{item.name}}
  16. </div>
  17. </div>
  18. <div class="share-item copy-btn" @click="clickCopy" v-click-log="state.log_invite_copy_btn_click"
  19. :data-clipboard-text="state.detail.inviteCopyUrl">
  20. <img :src="require('@/assets/svg/icon-copy-url-teasure.svg')" alt="">
  21. <div class="name">
  22. Copy URL
  23. </div>
  24. </div>
  25. </div>
  26. </div>
  27. </div>
  28. <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false"
  29. :disabled="state.open_btn.disabled" v-show-log="state.log_invite_btn_show" :loading="state.btn_loading"
  30. v-click-log="state.log_invite_btn_click" @onClick="clickBtn" font-weight="600"></v-btn>
  31. <div class="mask" v-show="showShareTips">
  32. <div class="content">
  33. <img class="icon-loading" :src="require('@/assets/svg/icon-tweet-loading.svg')" />
  34. <div class="text">
  35. Link copied to clipboard
  36. <br/>
  37. Opening {{selectShareApp.name }}
  38. </div>
  39. </div>
  40. </div>
  41. </div>
  42. </template>
  43. <script setup>
  44. import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
  45. import { inviteChannel } from '@/http/treasure'
  46. import { inject, onMounted, ref } from 'vue'
  47. import Report from "@/log-center/log"
  48. import { getFrontConfig } from "@/http/account";
  49. import { faceShareRedirectUrl } from '@/http/configAPI'
  50. import { setChromeStorage } from '@/uilts/chromeExtension.js'
  51. let ClipboardJS = require('clipboard');
  52. let state = inject('state')
  53. state.log_invite_btn_show = {
  54. businessType: Report.businessType.buttonView,
  55. pageSource: Report.pageSource.inviteFriendsPage,
  56. objectType: Report.objectType.openChestButton,
  57. redPacketType: Report.redPacketType.treasure,
  58. shareLinkId: state.invite_code,
  59. myShareLinkId: state.detail.inviteCopyUrl,
  60. currentInvitedNum: state.inviteCount,
  61. postId: state.postId
  62. }
  63. state.log_invite_btn_click = {
  64. businessType: Report.businessType.buttonClick,
  65. pageSource: Report.pageSource.inviteFriendsPage,
  66. objectType: Report.objectType.openChestButton,
  67. redPacketType: Report.redPacketType.treasure,
  68. shareLinkId: state.invite_code,
  69. myShareLinkId: state.detail.inviteCopyUrl,
  70. currentInvitedNum: state.inviteCount,
  71. postId: state.postId
  72. }
  73. state.log_invite_copy_btn_click = {
  74. businessType: Report.businessType.buttonClick,
  75. pageSource: Report.pageSource.inviteFriendsPage,
  76. objectType: Report.objectType.copyButton,
  77. redPacketType: Report.redPacketType.treasure,
  78. shareLinkId: state.invite_code,
  79. myShareLinkId: state.detail.inviteCopyUrl,
  80. currentInvitedNum: state.inviteCount,
  81. postId: state.postId
  82. }
  83. let facebookAppConfig = {
  84. facebookAppId: "",
  85. faceShareRedirectUrl
  86. };
  87. let selectShareApp = ref({});
  88. let showShareTips = ref(false);
  89. let followUserStr = ref('');
  90. onMounted(() => {
  91. state.btn_loading = false
  92. setFrontConfig();
  93. initInviteChannel();
  94. getFollowUserStr();
  95. })
  96. const getFollowUserStr = () => {
  97. let arr = [];
  98. if(state.follows && state.follows.length) {
  99. for(let i = 0; i < state.follows.length; i++) {
  100. let item = state.follows[i];
  101. arr.push('@'+item.name);
  102. }
  103. }
  104. followUserStr.value = arr.join(" or ");
  105. }
  106. chrome.management.onDisabled.addListener(() => {
  107. initInviteChannel()
  108. })
  109. chrome.management.onEnabled.addListener(() => {
  110. initInviteChannel()
  111. })
  112. chrome.management.onInstalled.addListener(() => {
  113. initInviteChannel()
  114. })
  115. chrome.management.onUninstalled.addListener(() => {
  116. initInviteChannel()
  117. })
  118. let linePluginInstalled
  119. const initInviteChannel = () => {
  120. try {
  121. chrome.management.get('ophjlpahpchlmihnnnihgmmeilfjmjjc', (res) => {
  122. if ((res && linePluginInstalled == 1) || (!res && linePluginInstalled == 0)) {
  123. return
  124. }
  125. if (res) {
  126. linePluginInstalled = 1
  127. } else {
  128. linePluginInstalled = 0
  129. }
  130. inviteChannel({
  131. params: {
  132. linePluginInstalled,
  133. postId: state.postId
  134. }
  135. }).then((res) => {
  136. if (res.code == 0) {
  137. state.share_list = res.data
  138. }
  139. })
  140. })
  141. } catch (error) {
  142. console.error(error)
  143. }
  144. }
  145. async function clickBtn() {
  146. let _userInfo = await state.checkIsLogin()
  147. if (!_userInfo) {
  148. return
  149. }
  150. state.btn_loading = true
  151. state.treasureOpen()
  152. }
  153. const clickShare = (item) => {
  154. var clipboard = new ClipboardJS('.share-item');
  155. clipboard.on('success', function (e) {
  156. // state.toast.txt = 'Copy Successfully'
  157. // state.toast.has_icon = true
  158. // state.toast.show = true
  159. // setTimeout(() => {
  160. // state.toast.show = false
  161. // }, 2000)
  162. e.clearSelection();
  163. })
  164. showShareTips.value = true;
  165. selectShareApp.value = item;
  166. if (item.name == 'facebook') {
  167. setChromeStorage({
  168. shareFacebookData: JSON.stringify({
  169. contentStr: item.inviteContent
  170. })
  171. })
  172. let cbParams = {
  173. bizType: 'TEASURE_INVITE'
  174. }
  175. let url = `https://www.facebook.com/dialog/share?app_id=${facebookAppConfig.facebookAppId}&display=popup&href=${item.treasureInviteUrl}&redirect_uri=${facebookAppConfig.faceShareRedirectUrl}?params=${JSON.stringify(cbParams)}`;
  176. setTimeout(() => {
  177. showShareTips.value = false;
  178. chrome.windows.create({
  179. width: 800,
  180. type: 'normal',
  181. url
  182. }, function (window) {
  183. })
  184. }, 1000)
  185. } else {
  186. setTimeout(() => {
  187. showShareTips.value = false;
  188. chrome.tabs.create({
  189. url: item.redirectPath
  190. });
  191. }, 1000)
  192. }
  193. Report.reportLog({
  194. businessType: Report.businessType.buttonClick,
  195. pageSource: Report.pageSource.inviteFriendsPage,
  196. objectType: Report.objectType.channelButton,
  197. shareLinkId: state.invite_code,
  198. myShareLinkId: state.detail.inviteCopyUrl,
  199. currentInvitedNum: state.inviteCount,
  200. postId: state.postId
  201. }, {
  202. 'channel-name': item.name
  203. });
  204. }
  205. const setFrontConfig = () => {
  206. getFrontConfig({
  207. params: {},
  208. }).then((res) => {
  209. if (res.code == 0) {
  210. facebookAppConfig.facebookAppId = res.data.fbClientId;
  211. }
  212. });
  213. };
  214. const clickCopy = () => {
  215. var clipboard = new ClipboardJS('.copy-btn');
  216. clipboard.on('success', function (e) {
  217. state.toast.txt = 'Copy Successfully'
  218. state.toast.has_icon = true
  219. state.toast.show = true
  220. setTimeout(() => {
  221. state.toast.show = false
  222. }, 2000)
  223. e.clearSelection();
  224. })
  225. clipboard.on('error', function (e) {
  226. state.toast.txt = 'Copy Error'
  227. state.toast.has_icon = false
  228. state.toast.show = true
  229. setTimeout(() => {
  230. state.toast.show = false
  231. }, 2000)
  232. })
  233. }
  234. </script>
  235. <style lang="scss" scoped>
  236. .invite-friends {
  237. padding: 9px 14px 14px 14px;
  238. background: #fff;
  239. box-sizing: border-box;
  240. .invite-friends-content {
  241. max-height: 242px;
  242. overflow-y: auto;
  243. margin-bottom: 10px;
  244. box-sizing: border-box;
  245. .invite-friends-content-head {
  246. margin-bottom: 18px;
  247. padding: 0 6px;
  248. box-sizing: border-box;
  249. .title {
  250. font-weight: 900;
  251. font-size: 18px;
  252. margin-bottom: 7px;
  253. }
  254. .info {
  255. font-weight: 400;
  256. font-size: 12px;
  257. color: #7A7A7A;
  258. line-height: 15px;
  259. }
  260. }
  261. .invite-friends-content-body {
  262. position: relative;
  263. .tips {
  264. position: absolute;
  265. top: -42px;
  266. left: 0;
  267. width: 146px;
  268. }
  269. .share-list-active {
  270. background: rgba(29, 155, 240, 0.1);
  271. border: 1.5px solid #1D9BF0 !important;
  272. border-radius: 10px;
  273. }
  274. .share-list {
  275. display: flex;
  276. flex-wrap: wrap;
  277. width: 100%;
  278. box-sizing: border-box;
  279. border: 1.5px solid #fff;
  280. .share-item {
  281. user-select: none;
  282. width: 20%;
  283. display: flex;
  284. flex-direction: column;
  285. align-items: center;
  286. justify-content: center;
  287. padding: 8px 2px;
  288. box-sizing: border-box;
  289. border-radius: 12px;
  290. cursor: pointer;
  291. img {
  292. width: 40px;
  293. height: 40px;
  294. border-radius: 100px;
  295. margin-bottom: 8px;
  296. }
  297. .name {
  298. font-weight: 400;
  299. font-size: 12px;
  300. color: #898989;
  301. width: 100%;
  302. overflow: hidden;
  303. text-overflow: ellipsis; //文本溢出显示省略号
  304. white-space: nowrap;
  305. text-align: center;
  306. }
  307. }
  308. .share-item:hover {
  309. background: #E3E3E4;
  310. }
  311. }
  312. }
  313. }
  314. .mask {
  315. position: fixed;
  316. top: 0;
  317. left: 0;
  318. width: 375px;
  319. height: 100%;
  320. background: rgba($color: #000000, $alpha: 0.9);
  321. z-index: 1000;
  322. display: flex;
  323. align-items: center;
  324. justify-content: center;
  325. .content {
  326. text-align: center;
  327. }
  328. .icon-loading {
  329. width: 60px;
  330. height: 60px;
  331. animation: loading 1.5 1s linear;
  332. margin-bottom: 30px;
  333. }
  334. .text {
  335. font-weight: 600;
  336. font-size: 17px;
  337. color: #FFFFFF;
  338. }
  339. }
  340. @keyframes loading {
  341. 0% {
  342. transform: rotate(0);
  343. }
  344. 100% {
  345. transform: rotate(360deg);
  346. }
  347. }
  348. }
  349. </style>