preview.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <template>
  2. <div class="editor-preview-wrapper">
  3. <div class="top">
  4. <div class="card-container">
  5. <!-- 安装之后的卡片样式 -->
  6. <div class="content-after" v-show="installStatus" :style="{ 'width': reviewCanvasParams.width + 'px' }">
  7. <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
  8. <img :src="userInfo.avatarUrl" class="avatar" />
  9. <div class="article-wrapper">
  10. <div class="nickname">
  11. {{ userInfo.name }}
  12. </div>
  13. <div class="name">
  14. @{{ userInfo.nickName }}
  15. </div>
  16. </div>
  17. </div>
  18. <div class="after-cover-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
  19. <install-card :pre_view="true" :iframe_url="previewData.convertUrl"></install-card>
  20. </div>
  21. </div>
  22. <!-- 安装之前的卡片样式 -->
  23. <div class="content-before" v-show="!installStatus"
  24. :style="{ 'width': reviewCanvasParams.width + 'px' }">
  25. <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
  26. <img :src="userInfo.avatarUrl" class="avatar" />
  27. <div class="article-wrapper">
  28. <div class="nickname">
  29. {{ userInfo.name }}
  30. </div>
  31. <div class="name">
  32. @{{ userInfo.nickName }}
  33. </div>
  34. </div>
  35. </div>
  36. <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
  37. <img class="cover" v-if="previewData.linkImagePath && previewData.appId" :src="previewData.linkImagePath" />
  38. <iframe class="iframe"
  39. :src="previewData.convertUrl"
  40. v-else></iframe>
  41. <div class="bottom-bar">
  42. <div class="site-url">DeNet.me</div>
  43. <div class="desc">
  44. <template v-if="previewData.appId">
  45. {{previewData.currentApp.linkTitle}}
  46. </template>
  47. <template v-else>
  48. {{previewData.currentApp.defaultTit ? 'Install DeNet Plugin to Participate' : previewData.currentApp.name}}
  49. </template>
  50. </div>
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. <div class="font">
  56. Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
  57. </div>
  58. </div>
  59. <div class="bottom">
  60. <div class="btn" @click="publishHandler">NEXT</div>
  61. </div>
  62. </div>
  63. </template>
  64. <script setup>
  65. import { ref, defineEmits, reactive, defineProps, onMounted, nextTick, onUnmounted, watch } from "vue";
  66. import { message } from "ant-design-vue";
  67. import installCard from '@/view/content/tool-box/index.vue'
  68. import { postPublish } from "@/http/publishApi";
  69. import { getChromeStorage, setChromeStorage } from "@/uilts/chromeExtension"
  70. import { getUser } from "@/http/publishApi"
  71. let installStatus = ref(false);
  72. let userInfo = ref({});
  73. let submitIng = ref(false);
  74. let reviewCanvasParams = reactive({
  75. width: 620,
  76. zoom: 1
  77. });
  78. let timer = ref(null);
  79. let loadingHide = null;
  80. const props = defineProps({
  81. previewData: {
  82. type: Object,
  83. default: () => {
  84. return {
  85. convertUrl: '',
  86. originUrl: '',
  87. appId: ''
  88. }
  89. }
  90. },
  91. screenshotWebsiteData: {
  92. type: Object,
  93. default: () => {
  94. return {
  95. url: '',
  96. status: ''
  97. }
  98. }
  99. },
  100. showCom: {
  101. type: String,
  102. default: 'EDITOR'
  103. }
  104. })
  105. watch(() => props.screenshotWebsiteData,
  106. (newVal) => {
  107. let { appId } = props.previewData;
  108. if(loadingHide && !appId && (newVal.url || newVal.status)) {
  109. loadingHide();
  110. loadingHide = null;
  111. submitPublish();
  112. }
  113. },
  114. {
  115. deep: true
  116. })
  117. watch(() => props.showCom,
  118. (newVal) => {
  119. if(newVal == 'EDITOR' && loadingHide) {
  120. loadingHide();
  121. loadingHide = null;
  122. }
  123. },
  124. {
  125. deep: true
  126. })
  127. const emits = defineEmits(["publishFinish"]);
  128. const getUserInfo = (cb) => {
  129. getChromeStorage('userInfo', (res) => {
  130. if (res) {
  131. userInfo.value = res;
  132. }
  133. cb && cb(res);
  134. })
  135. }
  136. const getUserName = (screenName) => {
  137. getUser({
  138. params: {
  139. screenName
  140. }
  141. }).then(res => {
  142. console.log(res);
  143. if (res.code == 0) {
  144. userInfo.value.name = res.data.name || ''
  145. }
  146. });
  147. }
  148. const calcPreviewCanvasParams = () => {
  149. nextTick(() => {
  150. let containerDom = document.querySelector('.card-container');
  151. let domHeight = containerDom && containerDom.offsetHeight || 500;
  152. const canvasHeight = 780, canvasWidth = 620;
  153. if (domHeight < canvasHeight) {
  154. //比例: 高 / 宽
  155. let hWRatio = canvasHeight / canvasWidth;
  156. //缩小宽度 = 高度 / 比例
  157. let width = domHeight / hWRatio;
  158. if (width > canvasWidth) {
  159. width = canvasWidth;
  160. }
  161. //缩小比例
  162. let zoom = width / canvasWidth;
  163. if (zoom > 1) {
  164. zoom = 1;
  165. }
  166. reviewCanvasParams.width = width;
  167. reviewCanvasParams.zoom = zoom;
  168. } else {
  169. reviewCanvasParams.width = canvasWidth;
  170. reviewCanvasParams.zoom = 1;
  171. }
  172. });
  173. }
  174. const publishHandler = () => {
  175. let { appId } = props.previewData;
  176. if(loadingHide) {
  177. return;
  178. }
  179. if(!appId && !props.screenshotWebsiteData.url) {
  180. loadingHide = message.loading('loading...', 0);
  181. return;
  182. }
  183. submitPublish();
  184. }
  185. const submitPublish = () => {
  186. let {convertUrl, originUrl, appId, currentApp} = props.previewData;
  187. if(submitIng.value) {
  188. return;
  189. }
  190. setHistoryData(currentApp);
  191. let linkTitle = currentApp.defaultTit ? '' : currentApp.name;
  192. let postBizData = {
  193. convertUrl,
  194. originUrl,
  195. appId,
  196. linkTitle: !appId ? linkTitle : '',
  197. linkImagePath: props.screenshotWebsiteData.url
  198. };
  199. let data = {
  200. params: {
  201. postBizData: JSON.stringify(postBizData),
  202. postSrc: 1, // 1 twitter
  203. postType: 3, //3 Tool box
  204. },
  205. };
  206. submitIng.value = true;
  207. postPublish(data).then((res) => {
  208. submitIng.value = false;
  209. if (res.code == 0) {
  210. let publishRes = res.data;
  211. emits("publishFinish", { publishRes });
  212. } else {
  213. }
  214. }).catch((err) => {
  215. console.log(err);
  216. });
  217. }
  218. const setHistoryData = async (params) => {
  219. const maxLength = 9;
  220. let {list = []} = await getChromeStorage('toolBoxAppHistoryData') || {};
  221. if(list.length) {
  222. let hasSite = list.find(item => item.defaultUrl == params.defaultUrl);
  223. if(hasSite) {
  224. return;
  225. }
  226. list.unshift(params);
  227. if(list.length > maxLength) {
  228. list.length = maxLength;
  229. }
  230. setChromeStorage({ toolBoxAppHistoryData : JSON.stringify({
  231. list: list
  232. })})
  233. } else {
  234. setChromeStorage({ toolBoxAppHistoryData : JSON.stringify({
  235. list: [params]
  236. })})
  237. }
  238. };
  239. onMounted(() => {
  240. calcPreviewCanvasParams();
  241. getUserInfo((res) => {
  242. if (res) {
  243. getUserName(res.nickName);
  244. }
  245. clearInterval(timer.value);
  246. timer.value = setInterval(() => {
  247. installStatus.value = !installStatus.value;
  248. }, 3000)
  249. });
  250. window.addEventListener('resize', function () {
  251. calcPreviewCanvasParams();
  252. })
  253. })
  254. onUnmounted(() => {
  255. clearInterval(timer.value);
  256. })
  257. </script>
  258. <style lang="scss" scoped>
  259. .editor-preview-wrapper {
  260. width: 100%;
  261. height: 100%;
  262. .top {
  263. width: 100%;
  264. height: calc(100% - 80px);
  265. display: flex;
  266. align-items: center;
  267. justify-content: center;
  268. overflow-y: auto;
  269. padding: 20px 0;
  270. box-sizing: border-box;
  271. .card-container {
  272. height: 100%;
  273. margin-right: 50px;
  274. .content-after,
  275. .content-before {
  276. position: relative;
  277. }
  278. .head {
  279. position: absolute;
  280. z-index: 1100;
  281. top: 20px;
  282. left: 17px;
  283. display: flex;
  284. .avatar {
  285. width: 47px;
  286. height: 47px;
  287. border-radius: 50%;
  288. object-fit: cover;
  289. margin-right: 13px;
  290. }
  291. .article-wrapper {
  292. display: flex;
  293. .nickname {
  294. font-weight: 500;
  295. }
  296. .nickname,
  297. .name {
  298. font-size: 15px;
  299. }
  300. .name {
  301. color: #566370;
  302. margin-left: 7px;
  303. }
  304. }
  305. }
  306. .content-after {
  307. background: url('@/assets/img/img-tool-box-preview-after.png');
  308. width: 387px;
  309. height: 100%;
  310. background-size: contain;
  311. background-repeat: no-repeat;
  312. border: 1px solid #D1D9DD;
  313. border-radius: 13px;
  314. box-sizing: border-box;
  315. .after-cover-wrapper {
  316. position: absolute;
  317. z-index: 100;
  318. top: 108px;
  319. left: 78px;
  320. width: 425px;
  321. height: 458px;
  322. border-radius: 10px;
  323. // border: 1px solid #D1D9DD;
  324. }
  325. }
  326. .content-before {
  327. background: url('@/assets/img/img-tool-box-preview-before.png');
  328. background-size: contain;
  329. background-repeat: no-repeat;
  330. height: 100%;
  331. border: 1px solid #D1D9DD;
  332. border-radius: 13px;
  333. box-sizing: border-box;
  334. .card-wrapper {
  335. width: 505px;
  336. height: 338px;
  337. border: 1px solid #D1D9DD;
  338. background: #ffffff;
  339. box-sizing: border-box;
  340. overflow: hidden;
  341. position: relative;
  342. box-sizing: border-box;
  343. border-radius: 16px;
  344. left: 73px;
  345. top: 90px;
  346. .iframe {
  347. height: calc(100% - 73px);
  348. width: 100%;
  349. border: none;
  350. pointer-events: none;
  351. cursor: default;
  352. }
  353. .cover {
  354. height: calc(100% - 73px);
  355. width: 100%;
  356. object-fit: contain;
  357. }
  358. .bottom-bar {
  359. width: 100%;
  360. height: 73px;
  361. padding: 10px 10px 0 13px;
  362. border-top: 1px solid rgba(0, 0, 0, 0.3);
  363. .site-url {
  364. color: #566370;
  365. font-size: 14px;
  366. line-height: 20px;
  367. }
  368. .desc {
  369. font-weight: 500;
  370. font-size: 15px;
  371. line-height: 21px;
  372. font-weight: 500;
  373. }
  374. }
  375. }
  376. }
  377. }
  378. .font {
  379. width: 300px;
  380. font-weight: 600;
  381. font-size: 20px;
  382. span {
  383. color: #1D9BF0;
  384. }
  385. }
  386. }
  387. .bottom {
  388. width: 100%;
  389. height: 80px;
  390. box-shadow: 0px -1px 0px #ECECEC;
  391. box-sizing: border-box;
  392. border-bottom-left-radius: 16px;
  393. display: flex;
  394. align-items: center;
  395. justify-content: flex-end;
  396. .btn {
  397. width: 200px;
  398. height: 50px;
  399. background: #1D9BF0;
  400. border-radius: 10000px;
  401. display: flex;
  402. align-items: center;
  403. justify-content: center;
  404. font-weight: 700;
  405. font-size: 18px;
  406. color: #fff;
  407. margin-right: 30px;
  408. cursor: pointer;
  409. }
  410. }
  411. }
  412. </style>