|
1 | | -import React, { h, Component } from 'preact'; |
| 1 | +import React, {Component} from 'preact'; |
2 | 2 | import {saveAs} from 'file-saver' |
3 | 3 | import UserCodeMirror from './UserCodeMirror.jsx'; |
4 | 4 | import Toolbox from './Toolbox.jsx'; |
5 | 5 | import Tabs from './Tabs.jsx'; |
6 | | -import { computeHtml, computeCss, computeJs } from '../computes'; |
7 | | -import { modes, HtmlModes, CssModes, JsModes } from '../codeModes'; |
8 | | -import { log, loadJS, getCompleteHtml } from '../utils'; |
9 | | -import { writeFileAsync} from "../WriteFile"; |
| 6 | +import {computeCss, computeHtml, computeJs} from '../computes'; |
| 7 | +import {CssModes, HtmlModes, JsModes, modes} from '../codeModes'; |
| 8 | +import {getCompleteHtml, loadJS, log} from '../utils'; |
| 9 | +import {writeFileAsync} from "../WriteFile"; |
10 | 10 | import Vue from '!!file-loader!vue/dist/vue'; |
11 | 11 | import Vuex from '!!file-loader!vuex/dist/vuex'; |
12 | 12 | import vueSequence from '!!file-loader!vue-sequence'; |
13 | 13 | import vueSequenceCss from '!!file-loader!vue-sequence/dist/vue-sequence.css'; |
14 | 14 |
|
15 | | -import { Button } from './common'; |
16 | | -import { SplitPane } from './SplitPane.jsx'; |
17 | | -import { trackEvent } from '../analytics'; |
| 15 | +import {Button} from './common'; |
| 16 | +import {SplitPane} from './SplitPane.jsx'; |
| 17 | +import {trackEvent} from '../analytics'; |
18 | 18 | import CodeMirror from '../CodeMirror'; |
19 | 19 | import 'codemirror/mode/javascript/javascript.js' |
20 | | -import { Console } from './Console'; |
21 | | -import { deferred } from '../deferred'; |
| 20 | +import {Console} from './Console'; |
| 21 | +import {deferred} from '../deferred'; |
22 | 22 | import CssSettingsModal from './CssSettingsModal'; |
23 | 23 | import codeService from '../services/code_service' |
| 24 | +import {alertsService} from '../notifications'; |
24 | 25 |
|
25 | 26 | const minCodeWrapSize = 33; |
26 | 27 |
|
@@ -445,81 +446,44 @@ export default class ContentWrap extends Component { |
445 | 446 | trackEvent('ui', 'paneHeaderDblClick', codeWrapParent.dataset.type); |
446 | 447 | } |
447 | 448 | async exportPngClickHandler(e) { |
448 | | - const mountingPoint = this.frame.contentWindow.document.getElementById('diagram'); |
449 | | - // eslint-disable-next-line |
450 | | - const png = await mountingPoint.getElementsByClassName('frame')[0].parentElement.__vue__.toBlob(); |
| 449 | + const png = await this.getPngBlob(); |
451 | 450 | saveAs(png, 'zenuml.png'); |
452 | 451 | trackEvent('ui', 'downloadPng'); |
453 | 452 | } |
454 | 453 |
|
455 | | - async exportJpegClickHandler(e) { |
| 454 | + async getPngBlob() { |
456 | 455 | const mountingPoint = this.frame.contentWindow.document.getElementById('diagram'); |
457 | 456 | // eslint-disable-next-line |
458 | | - const jpeg = await mountingPoint.getElementsByClassName('frame')[0].parentElement.__vue__.toJpeg(); |
459 | | - saveAs(jpeg, 'zenuml.jpeg'); |
460 | | - trackEvent('ui', 'downloadJpeg'); |
| 457 | + return await mountingPoint.getElementsByClassName('frame')[0].parentElement.__vue__.toBlob(); |
461 | 458 | } |
462 | 459 |
|
463 | | - async copyPngClickHandler(e) { |
464 | | - console.log(e); |
465 | | - const mountingPoint = this.frame.contentWindow.document.getElementById('diagram'); |
466 | | - // eslint-disable-next-line |
467 | | - const png = await mountingPoint.getElementsByClassName('frame')[0].parentElement.__vue__.toBlob(); |
468 | | - this.copyPngToClipboard(png); |
469 | | - trackEvent('ui', 'copyPng'); |
470 | | - } |
471 | | - |
472 | | - async copyPngClickHandlerBySafari3(e) { |
473 | | - console.log(e); |
474 | | - const mountingPoint = this.frame.contentWindow.document.getElementById('diagram'); |
475 | | - // eslint-disable-next-line |
| 460 | + async copyImageClickHandler(e) { |
| 461 | + if(!navigator.clipboard || !navigator.clipboard.write){ |
| 462 | + this.showCopyErrorNotice(); |
| 463 | + trackEvent('ui', 'copyImageFailed1'); |
| 464 | + return; |
| 465 | + } |
476 | 466 | navigator.clipboard.write([ |
477 | 467 | new ClipboardItem({ |
478 | 468 | "image/png": new Promise(async resolve => { |
479 | | - const png = await mountingPoint.getElementsByClassName('frame')[0].parentElement.__vue__.toBlob(); |
| 469 | + const png = await this.getPngBlob(); |
480 | 470 | resolve(png); |
481 | 471 | }) |
482 | 472 | }) |
483 | 473 | ]).then( |
484 | | - r => console.log("success", r), |
485 | | - reason => console.log("failed", reason) |
| 474 | + () => alertsService.add("PNG file was copied"), |
| 475 | + err => { |
| 476 | + this.showCopyErrorNotice(); |
| 477 | + console.log(err); |
| 478 | + trackEvent('ui', 'copyImageFailed2'); |
| 479 | + } |
486 | 480 | ); |
487 | | - trackEvent('ui', 'copyPng'); |
| 481 | + trackEvent('ui', 'copyImage'); |
488 | 482 | } |
489 | 483 |
|
490 | | - copyPngToClipboard(imageData) { |
491 | | - if (navigator.permissions && navigator.permissions.query) { |
492 | | - const status = navigator.permissions.query({name: 'clipboard_write'}); |
493 | | - console.log(status); |
494 | | - } |
495 | | - console.log(navigator.userAgent); |
496 | | - let isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); |
497 | | - console.log(isSafari); |
498 | | - isSafari = false; |
499 | | - if (isSafari) { |
500 | | - console.log("safari") |
501 | | - navigator.clipboard.write([ |
502 | | - new ClipboardItem({ |
503 | | - "image/png": new Promise(async (resolve, reject) => { |
504 | | - try { |
505 | | - resolve(new Blob([imageData], { type: "image/png" })); |
506 | | - } catch (err) { |
507 | | - reject(err); |
508 | | - } |
509 | | - }), |
510 | | - }), |
511 | | - ]).then(() => console.log("success") |
512 | | - ).catch((err) => |
513 | | - // Error |
514 | | - console.error("Error:", err) |
515 | | - ); |
516 | | - } else { |
517 | | - const clipboardItem = new ClipboardItem({'image/png': imageData}); |
518 | | - navigator.clipboard.write([clipboardItem]).then( |
519 | | - (value) => console.log("Copied to clipboard successfully!", value), |
520 | | - (reason) => console.error("Copied to clipboard failed!: ", reason) |
521 | | - ) |
522 | | - } |
| 484 | + |
| 485 | + showCopyErrorNotice() { |
| 486 | + alertsService.add("Copy failed, please try on another browser or upgrade your browser!"); |
523 | 487 | } |
524 | 488 |
|
525 | 489 | shareClickHandler(e) { |
@@ -1085,24 +1049,10 @@ export default class ContentWrap extends Component { |
1085 | 1049 | <span class="material-symbols-outlined">file_download</span> |
1086 | 1050 | <span>PNG</span> |
1087 | 1051 | </Button> |
1088 | | - <Button |
1089 | | - className="btn--dark button icon-button hint--rounded hint--bottom-left" |
1090 | | - aria-label="Export as JPEG" |
1091 | | - onClick={this.exportJpegClickHandler.bind(this)}> |
1092 | | - <span class="material-symbols-outlined">file_download</span> |
1093 | | - <span>JPEG</span> |
1094 | | - </Button> |
1095 | | - <Button |
1096 | | - className="btn--dark button icon-button hint--rounded hint--bottom-left" |
1097 | | - aria-label="Copy PNG to Clipboard" |
1098 | | - onClick={this.copyPngClickHandler.bind(this)}> |
1099 | | - <span class="material-symbols-outlined">file_copy</span> |
1100 | | - <span>Copy PNG File By Chrome</span> |
1101 | | - </Button> |
1102 | 1052 | <Button |
1103 | 1053 | className="btn--dark button icon-button hint--rounded hint--bottom-left" |
1104 | 1054 | aria-label="Copy PNG to Clipboard" |
1105 | | - onClick={this.copyPngClickHandlerBySafari3.bind(this)}> |
| 1055 | + onClick={this.copyImageClickHandler.bind(this)}> |
1106 | 1056 | <span class="material-symbols-outlined">file_copy</span> |
1107 | 1057 | <span>Copy PNG File</span> |
1108 | 1058 | </Button> |
|
0 commit comments