main.js 5.0 KB

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