renderer.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. const { ipcRenderer } = require('electron');
  2. const remote = require("electron").remote;
  3. var dialog = remote.dialog;
  4. var fs = require('fs');
  5. let StateData = {
  6. file_path: '',
  7. last_state: null
  8. }
  9. function showAlert(msg, speed=0.02) {
  10. var div = '<div class="floating" id="message">'+msg+'</div>';
  11. document.getElementById("container").innerHTML = div;
  12. var s = document.getElementById('message').style;
  13. s.opacity = 1;
  14. (function fade(){(s.opacity-=speed)<0?s.display="none":setTimeout(fade,40)})();
  15. }
  16. function set_caculator_state(des_file_data) {
  17. state = JSON.parse(des_file_data);
  18. try {
  19. calculator.setState(state);
  20. }
  21. catch(err) {
  22. calculator.setBlank();
  23. }
  24. }
  25. function saveText(text, file){
  26. fs.writeFileSync(file, text);
  27. showAlert('Saved successfully. ;)');
  28. }
  29. function setTitle() {
  30. if (StateData.file_path)
  31. document.title = "Desmos - " + StateData.file_path;
  32. else
  33. document.title = "Desmos - * Untitled";
  34. ipcRenderer.send('renderer-request', {msg: 'TitleChanged', data: StateData.file_path});
  35. }
  36. setInterval( function(){
  37. if (isSaved()) return;
  38. else if (StateData.file_path)
  39. document.title = "Desmos - * "+StateData.file_path;
  40. }, 1000);
  41. function newFile() {
  42. var canceled = !askSaveIfNeed();
  43. if (canceled) return;
  44. calculator.setBlank();
  45. StateData.file_path = '';
  46. setTitle();
  47. }
  48. function openFile(filePath=null, init=false) {
  49. if (!init) {
  50. if (canceled) return;
  51. var canceled = !askSaveIfNeed();
  52. }
  53. if (!filePath && init) { return; }
  54. if (!filePath) {
  55. filePaths = dialog.showOpenDialog({filters: [ {name: 'des', extensions: ['des'] }]});
  56. if (!filePaths) return;
  57. filePath = filePaths[0];
  58. }
  59. fs.readFile(filePath, (err, data) => {
  60. if(err){
  61. showAlert("Error on openning :( " + err.message);
  62. calculator.setBlank();
  63. }
  64. set_caculator_state(data);
  65. StateData.file_path = filePath;
  66. StateData.last_state = data;
  67. setTitle();
  68. });
  69. }
  70. function saveFile() {
  71. if(!StateData.file_path){
  72. const file = dialog.showSaveDialog(remote.getCurrentWindow(), {
  73. filters: [
  74. { name: "Desmos Files", extensions: ['des'] }]
  75. });
  76. if(file) StateData.file_path=file;
  77. }
  78. if(StateData.file_path){
  79. var state = calculator.getState();
  80. StateData.last_state = state;
  81. var state_content = JSON.stringify(state, null, 4);
  82. saveText(state_content, StateData.file_path);
  83. setTitle();
  84. }
  85. }
  86. function saveAsFile() {
  87. const file = dialog.showSaveDialog(remote.getCurrentWindow(), {
  88. filters: [
  89. { name: "Desmos Files", extensions: ['des'] }]
  90. });
  91. if(file) StateData.file_path=file;
  92. if(StateData.file_path){
  93. var state = calculator.getState();
  94. StateData.last_state = state;
  95. var state_content = JSON.stringify(state, null, 4);
  96. saveText(state_content, StateData.file_path);
  97. setTitle();
  98. }
  99. }
  100. function exportImage() {
  101. var image = calculator.screenshot({
  102. width: remote.width,
  103. height: remote.height,
  104. targetPixelRatio: 2
  105. });
  106. var image_data = image.replace(/^data:image\/png;base64,/, "");
  107. dialog.showSaveDialog({filters: [ {name: 'png', extensions: ['png'] }]},
  108. (fileName) => {
  109. if (fileName === undefined){
  110. console.log("You didn't open the file.");
  111. return;
  112. }
  113. // fileName is a string that contains the path and filename created in the save file dialog.
  114. fs.writeFile(fileName, image_data, 'base64', (err) => {
  115. if(err){
  116. alert("An error ocurred creating the file. :( "+ err.message)
  117. }
  118. showAlert("Succesfully exported. ;)");
  119. });
  120. });
  121. }
  122. function isStateNull() {
  123. if (StateData.last_state == null && calculator.getState().expressions.list[0].latex === undefined)
  124. return true;
  125. else return false;
  126. }
  127. function isSaved() {
  128. if (isStateNull()) return true;
  129. if (StateData.file_path == "" || StateData.last_state == null)
  130. return false;
  131. else {
  132. if (JSON.stringify(calculator.getState().extensions) == JSON.stringify(StateData.last_state.extensions))
  133. return true;
  134. else
  135. return false;
  136. }
  137. }
  138. function askSaveIfNeed(){
  139. if(isSaved()) return true;
  140. const response = dialog.showMessageBox(remote.getCurrentWindow(), {
  141. message: 'Do you want to save the current document?',
  142. type: 'question',
  143. buttons: [ 'Yes', 'No', 'Cancel' ]
  144. });
  145. // Yes to save
  146. if (response == 0)
  147. saveFile();
  148. if (response == 2)
  149. return false;
  150. else
  151. return true;
  152. }
  153. function exitApp() {
  154. var exit = askSaveIfNeed();
  155. if (exit) {
  156. showAlert('Exiting...', 0);
  157. setTimeout(()=>{
  158. ipcRenderer.sendSync('renderer-response', {msg: 'Exit'});
  159. }, 600);
  160. }
  161. }
  162. ipcRenderer.on('mainprocess-request', (event, arg) => {
  163. console.log(arg);
  164. switch (arg.msg) {
  165. case 'NewFile': newFile(); break;
  166. case 'Init': openFile(arg.data, true); break;
  167. case 'OpenFile': openFile(); break;
  168. case 'SaveFile': saveFile(); break;
  169. case 'SaveAsFile': saveAsFile(); break;
  170. case 'ExportImage': exportImage(); break;
  171. case 'Undo': calculator.undo(); break;
  172. case 'Redo': calculator.redo(); break;
  173. case 'Clear': calculator.setBlank(); break;
  174. case 'Exitting': exitApp(); break;
  175. default: break;
  176. }
  177. });
  178. document.addEventListener("keydown", event => {
  179. switch (event.key) {
  180. case "Escape":
  181. if (remote.getCurrentWindow().isFullScreen()) {
  182. remote.getCurrentWindow().setFullScreen(false);
  183. } else {
  184. remote.getCurrentWindow().close();
  185. }
  186. break;
  187. }
  188. });
  189. ipcRenderer.send('renderer-request', {msg: 'ToInit'})
  190. // document.ondragover = document.ondrop = (ev) => {
  191. // ev.preventDefault()
  192. // }
  193. // document.body.ondrop = (ev) => {
  194. // console.log(ev.dataTransfer.files[0].path)
  195. // ev.preventDefault()
  196. // }