preview.vue 13 KB

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