index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div class="denet-message" v-show="state.list.length > 0">
  3. <template v-for="item in state.list" :key="item.createTimestamp">
  4. <div class="denet-message-area" @click="clickItem(item)" v-if="item.bizType == 2">
  5. <img :src="require('@/assets/img/icon-message-fail.png')" alt />
  6. <span>You were not selected from {{item.bizData.twitterAccount}}'s giveaway events... Click to see more giveaways!</span>
  7. <div class="denet-message-close" @click.stop="clickClose(item)">
  8. <img :src="require('@/assets/img/icon-message-close.png')" alt />
  9. </div>
  10. </div>
  11. <div class="denet-message-area" @click="clickItem(item)" v-if="item.bizType == 1">
  12. <img :src="require('@/assets/img/icon-message-win.png')" alt />
  13. <span>Congratulations! You won <b class="denet-message-money"> {{getPrize(item.bizData)}}</b> from {{item.bizData.twitterAccount}}'s giveaway!🎉</span>
  14. <div class="denet-message-close" @click.stop="clickClose(item)">
  15. <img :src="require('@/assets/img/icon-message-close.png')" alt />
  16. </div>
  17. </div>
  18. <!-- 自定义系统消息 -->
  19. <div class="denet-message-area" @click="clickItem(item)" v-if="item.bizType == 3">
  20. <img :src="item.bizData.icon" alt />
  21. <span>{{ item.bizData.text }}</span>
  22. <div class="denet-message-close" @click.stop="clickClose(item)">
  23. <img :src="require('@/assets/img/icon-message-close.png')" alt />
  24. </div>
  25. </div>
  26. </template>
  27. </div>
  28. </template>
  29. <script setup>
  30. import { onMounted, reactive } from "vue";
  31. import { RewardType } from '@/types';
  32. let state = reactive({
  33. list: [],
  34. })
  35. let timer, now_time
  36. // 获取奖励
  37. const getPrize = (item) => {
  38. const { lotteryMoney, lotteryTokenSymbol, twitterAccount, rewardType, customizedReward } = item;
  39. if (rewardType === RewardType.custom) {
  40. return customizedReward;
  41. } else {
  42. return `${item.bizData.lotteryMoney} ${item.bizData.lotteryTokenSymbol}`
  43. }
  44. }
  45. // 过5秒消失逻辑
  46. const overTimeClose = () => {
  47. if (timer) {
  48. return
  49. }
  50. timer = setInterval(() => {
  51. if (state.list.length == 0) {
  52. clearInterval(timer)
  53. timer = null
  54. }
  55. now_time = new Date().getTime()
  56. for (let i in state.list) {
  57. if ((now_time - state.list[i].read_time) >= 5000) {
  58. state.list.splice(i, 1)
  59. }
  60. }
  61. }, 1000)
  62. }
  63. const clickClose = (item) => {
  64. // 通知已读
  65. for (let i in state.list) {
  66. if (item.id == state.list[i].id) {
  67. state.list.splice(i, 1)
  68. }
  69. }
  70. }
  71. const clickItem = (item) => {
  72. switch (String(item.bizType)) {
  73. case '1':
  74. // 跳转详情页
  75. window.open(`https://twitter.com/${item.bizData.twitterAccount}/status/${item.bizData.twitterId}`)
  76. break;
  77. case '2':
  78. window.open('https://twitter.com/search?q=%23DeNet&src=typed_query')
  79. break;
  80. case '3':
  81. // 自定义消息
  82. window.open(item.bizData.jumpUrl)
  83. break
  84. }
  85. }
  86. // 读取消息
  87. const readMessage = (id = 0) => {
  88. chrome.runtime.sendMessage({
  89. actionType: "CONTENT_HTTP_NET_WORK",
  90. funcName: '通知已读',
  91. data: {
  92. url: '/notice/read',
  93. params: {
  94. noticeId: id
  95. }
  96. }
  97. });
  98. }
  99. chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
  100. if (req.actionType == 'BACK_UNREAD_MESSAGE') {
  101. let data = req.data.data || []
  102. if (req.data.code == 0 && data.length > 0) {
  103. data.forEach((item) => {
  104. if (state.list.filter((filter_item) => { return filter_item.id == item.id }).length == 0) {
  105. item.bizData = JSON.parse(item.bizData)
  106. item.read_time = new Date().getTime()
  107. state.list.push(item)
  108. }
  109. readMessage(item.id)
  110. })
  111. overTimeClose()
  112. }
  113. }
  114. })
  115. </script>
  116. <style lang="scss" >
  117. #denet_message{
  118. text-align: left;
  119. }
  120. .denet-message {
  121. position: fixed;
  122. max-height: 100%;
  123. overflow: hidden;
  124. top: 0;
  125. right: 0;
  126. width: 500px;
  127. z-index: 9999;
  128. text-align: left;
  129. &-area {
  130. width: 344px;
  131. background: #FFFFFF;
  132. border-radius: 15px;
  133. min-height: 72px;
  134. position: relative;
  135. margin-top: 22px;
  136. display: flex;
  137. cursor: pointer;
  138. filter: drop-shadow(0px 5px 20px rgba(0, 0, 0, 0.22));
  139. margin-left: 129px;
  140. animation: right_to_left 1s;
  141. text-align: left;
  142. img:first-child {
  143. width: 40px;
  144. height: 40px;
  145. margin: 16px 14px 0 16px;
  146. }
  147. span {
  148. padding: 14px 26px 14px 0;
  149. font-style: normal;
  150. font-weight: 500;
  151. font-size: 14px;
  152. line-height: 20px;
  153. }
  154. .denet-message-money {
  155. color: #3D7CB4;
  156. }
  157. }
  158. &-area:last-child {
  159. margin-bottom: 50px;
  160. }
  161. &-close {
  162. border-radius: 100px;
  163. width: 24px;
  164. height: 24px;
  165. display: flex;
  166. justify-content: center;
  167. align-items: center;
  168. background: #F2F2F2;
  169. position: absolute;
  170. right: -10px;
  171. top: -10px;
  172. filter: drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.12));
  173. cursor: pointer;
  174. img:first-child {
  175. height: 10px;
  176. width: 10px;
  177. margin: 0;
  178. }
  179. }
  180. }
  181. @keyframes right_to_left {
  182. 0% {
  183. right: -400px;
  184. }
  185. 100% {
  186. right: 0;
  187. }
  188. }
  189. </style>