main.js 5.0 KB

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