main.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import 'codemirror/lib/codemirror.css';
  2. import './style.css';
  3. import 'codemirror/mode/toml/toml.js';
  4. import CodeMirror from 'codemirror';
  5. const { event, fs, path, tauri } = window.__TAURI__;
  6. class View {
  7. constructor() {
  8. Object.assign(this, {
  9. content: '',
  10. action_time: 0,
  11. is_auto_scroll: true,
  12. is_edit_mode: false,
  13. is_file_changed: false,
  14. is_form_changed: false,
  15. is_content_changed: false
  16. }, ...arguments);
  17. addEventListener('DOMContentLoaded', this.init.bind(this));
  18. }
  19. async init() {
  20. this.editor = this.renderEditor();
  21. this.editor.on('scroll', this.editorScroll.bind(this));
  22. this.editor.on('keypress', this.editorSave.bind(this));
  23. this.form = this.renderForm();
  24. this.form.addEventListener('change', this.formChange.bind(this));
  25. event.listen('__update__', this.appAction.bind(this));
  26. event.emit('__action__', '__init__');
  27. while (true) {
  28. let now = Date.now();
  29. try {
  30. await this.update();
  31. this.render();
  32. } catch (e) {
  33. console.error(e);
  34. }
  35. await new Promise(r => setTimeout(r, Math.max(0, 33 - (Date.now() - now))));
  36. }
  37. }
  38. async update() {
  39. if (this.is_file_changed) {
  40. this.is_file_changed = false;
  41. let now = Date.now(),
  42. file = await path.resolveResource(this.file);
  43. if (await fs.exists(file)) {
  44. let content = await fs.readTextFile(file);
  45. if (this.action_time < now) {
  46. this.content = content;
  47. this.is_content_changed = true;
  48. }
  49. } else {
  50. if (now >= this.action_time) {
  51. if (this.is_edit_mode) {
  52. this.content = `# https://github.com/rustdesk/rustdesk-server#env-variables
  53. RUST_LOG=info
  54. `;
  55. }
  56. this.is_content_changed = true;
  57. }
  58. console.warn(`${this.file} file is missing`);
  59. }
  60. }
  61. }
  62. async editorSave(editor, e) {
  63. if (e.ctrlKey && e.keyCode === 19 && this.is_edit_mode && !this.locked) {
  64. this.locked = true;
  65. try {
  66. let now = Date.now(),
  67. content = this.editor.doc.getValue(),
  68. file = await path.resolveResource(this.file);
  69. await fs.writeTextFile(file, content);
  70. event.emit('__action__', 'restart');
  71. } catch (e) {
  72. console.error(e);
  73. } finally {
  74. this.locked = false;
  75. }
  76. }
  77. }
  78. editorScroll(e) {
  79. let info = this.editor.getScrollInfo(),
  80. distance = info.height - info.top - info.clientHeight,
  81. is_end = distance < 1;
  82. if (this.is_auto_scroll !== is_end) {
  83. this.is_auto_scroll = is_end;
  84. this.is_form_changed = true;
  85. }
  86. }
  87. formChange(e) {
  88. switch (e.target.tagName.toLowerCase()) {
  89. case 'input':
  90. this.is_auto_scroll = e.target.checked;
  91. break;
  92. }
  93. }
  94. appAction(e) {
  95. let [action, data] = e.payload;
  96. switch (action) {
  97. case 'file':
  98. if (data === '.env') {
  99. this.is_edit_mode = true;
  100. this.file = `bin/${data}`;
  101. } else {
  102. this.is_edit_mode = false;
  103. this.file = `logs/${data}`;
  104. }
  105. this.action_time = Date.now();
  106. this.is_file_changed = true;
  107. this.is_form_changed = true;
  108. break;
  109. }
  110. }
  111. render() {
  112. if (this.is_form_changed) {
  113. this.is_form_changed = false;
  114. this.renderForm();
  115. }
  116. if (this.is_content_changed) {
  117. this.is_content_changed = false;
  118. this.renderEditor();
  119. }
  120. if (this.is_auto_scroll && !this.is_edit_mode) {
  121. this.renderScrollbar();
  122. }
  123. }
  124. renderForm() {
  125. let form = this.form || document.querySelector('form'),
  126. label = form.querySelectorAll('label'),
  127. input = form.querySelector('input');
  128. input.checked = this.is_auto_scroll;
  129. if (this.is_edit_mode) {
  130. label[0].style.display = 'none';
  131. label[1].style.display = 'block';
  132. } else {
  133. label[0].style.display = 'block';
  134. label[1].style.display = 'none';
  135. }
  136. return form;
  137. }
  138. renderEditor() {
  139. let editor = this.editor || CodeMirror.fromTextArea(document.querySelector('textarea'), {
  140. mode: { name: 'toml' },
  141. lineNumbers: true,
  142. autofocus: true
  143. });
  144. editor.setOption('readOnly', !this.is_edit_mode);
  145. editor.doc.setValue(this.content);
  146. editor.doc.clearHistory();
  147. this.content = '';
  148. editor.focus();
  149. return editor;
  150. }
  151. renderScrollbar() {
  152. let info = this.editor.getScrollInfo();
  153. this.editor.scrollTo(info.left, info.height);
  154. }
  155. }
  156. new View();