From dba23289fd970d1d075cf23eaae7e52d7da83aee Mon Sep 17 00:00:00 2001 From: 87owo <85057800+87owo@users.noreply.github.com> Date: Wed, 29 Apr 2026 17:41:00 +0800 Subject: [PATCH] Add files via upload --- Interface/static/js/main.js | 51 +++++++++++++++++++++++++------- PYAS.py | 58 ++++++++++++++++++++----------------- 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/Interface/static/js/main.js b/Interface/static/js/main.js index a2215c0..fb9a720 100644 --- a/Interface/static/js/main.js +++ b/Interface/static/js/main.js @@ -1591,10 +1591,21 @@ document.addEventListener('DOMContentLoaded', () => { }; document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => { - toggle.addEventListener('change', (e) => { + toggle.addEventListener('change', async (e) => { const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; - if (window.pywebview && switchMap[index]) { - window.pywebview.api.update_config(switchMap[index], e.target.checked); + const key = switchMap[index]; + if (window.pywebview && key) { + toggle.disabled = true; + try { + const result = await window.pywebview.api.update_config(key, e.target.checked); + if (result !== undefined && result !== null) { + toggle.checked = result; + } + } catch (err) { + toggle.checked = !e.target.checked; + } finally { + toggle.disabled = false; + } } }); }); @@ -1639,7 +1650,7 @@ document.addEventListener('DOMContentLoaded', () => { const searchInput = document.querySelector(`${containerSelector} .search-box input`); if (!container) return; - const render = (filterText = "") => { + container.renderData = (filterText = "") => { container.innerHTML = ''; dataList.forEach(item => { const displayStr = typeof item === 'object' ? item[displayKey] : item; @@ -1665,11 +1676,10 @@ document.addEventListener('DOMContentLoaded', () => { }); }; - render(searchInput ? searchInput.value : ""); + container.renderData(searchInput ? searchInput.value : ""); - if (searchInput && !searchInput.dataset.bound) { - searchInput.addEventListener('input', (e) => render(e.target.value)); - searchInput.dataset.bound = true; + if (searchInput) { + searchInput.oninput = (e) => container.renderData(e.target.value); } } @@ -1829,6 +1839,21 @@ document.addEventListener('DOMContentLoaded', () => { logWidget.scrollTop = logWidget.scrollHeight; } + const exportWindow = document.getElementById('log_export_window'); + if (exportWindow && exportWindow.classList.contains('active')) { + if (window.pywebview) { + window.pywebview.api.get_logs().then(logs => { + const logList = logs.reverse().map(log => { + let displayStr = `[${log.time_str}] ${log.level} | ${log.action}`; + if (log.source) displayStr += ` | ${log.source.split('\\').pop().split('/').pop()}`; + if (log.detail) displayStr += ` | ${log.detail}`; + return { display: displayStr, value: log.id }; + }); + renderManageList('#log_export_window', logList, 'display', 'value', true); + }); + } + } + if ((entry.action === 'System' && entry.detail === 'Engine Initialization Complete') || (entry.level === 'WARN' && entry.action === 'init_engine_thread')) { const overlay = document.getElementById('loading_overlay'); @@ -1908,8 +1933,14 @@ document.addEventListener('DOMContentLoaded', () => { window.pywebview.api.show_confirm(getMsg("提示"), confirmMsg).then(res => { if (res) { window.pywebview.api.clear_logs(checkedIds).then(() => { - document.querySelectorAll('#log_export_window .manage-list-item input[type="checkbox"]:checked').forEach(cb => { - cb.parentElement.remove(); + window.pywebview.api.get_logs().then(logs => { + const logList = logs.reverse().map(log => { + let displayStr = `[${log.time_str}] ${log.level} | ${log.action}`; + if (log.source) displayStr += ` | ${log.source.split('\\').pop().split('/').pop()}`; + if (log.detail) displayStr += ` | ${log.detail}`; + return { display: displayStr, value: log.id }; + }); + renderManageList('#log_export_window', logList, 'display', 'value', true); }); const successMsg = getMsg("選取的日誌已刪除。"); window.pywebview.api.show_alert(getMsg("提示"), successMsg, "info"); diff --git a/PYAS.py b/PYAS.py index 3aa335a..d5f3831 100644 --- a/PYAS.py +++ b/PYAS.py @@ -424,6 +424,7 @@ class WindowAPI: self.cloud_queue = queue.Queue() self.lock_driver = threading.RLock() + self.lock_update = threading.RLock() self.driver_port = None self.scan_running = False self.scan_finished = False @@ -503,36 +504,41 @@ class WindowAPI: self.write_log("WARN", "save_config", detail=str(e), success=False) def update_config(self, key, value): - with self.lock_config: - old_value = self.pyas_config.get(key) - if old_value != value: + with self.lock_update: + with self.lock_config: + old_value = self.pyas_config.get(key) + if old_value == value: + return value self.pyas_config[key] = value self.write_log("INFO", "Config Update", detail=f"[{key}] {old_value} -> {value}") self.save_config() - - if key == "process_switch" and value: - self.start_daemon_thread(self.protect_proc_thread) - elif key == "document_switch" and value: - self.start_daemon_thread(self.protect_file_thread) - elif key == "system_switch" and value: - self.start_daemon_thread(self.protect_system_thread) - elif key == "network_switch" and value: - self.start_daemon_thread(self.protect_net_thread) - elif key == "context_switch": - self.register_context_menu(value) - elif key == "driver_switch": - if value: - if self.install_system_driver(): - self.start_daemon_thread(self.pipe_server_thread) + + if key == "process_switch" and value: + self.start_daemon_thread(self.protect_proc_thread) + elif key == "document_switch" and value: + self.start_daemon_thread(self.protect_file_thread) + elif key == "system_switch" and value: + self.start_daemon_thread(self.protect_system_thread) + elif key == "network_switch" and value: + self.start_daemon_thread(self.protect_net_thread) + elif key == "context_switch": + self.register_context_menu(value) + elif key == "driver_switch": + if value: + if self.install_system_driver(): + self.start_daemon_thread(self.pipe_server_thread) + else: + with self.lock_config: + self.pyas_config[key] = False + self.write_log("INFO", "Config Update", detail=f"[{key}] True -> False") + self.save_config() + if self._window: + self._window.evaluate_js(f"if(window.revertSwitch) window.revertSwitch('{key}');") + return False else: - with self.lock_config: - self.pyas_config[key] = False - self.write_log("INFO", "Config Update", detail=f"[{key}] True -> False") - self.save_config() - if self._window: - self._window.evaluate_js(f"if(window.revertSwitch) window.revertSwitch('{key}');") - else: - self.stop_system_driver() + self.stop_system_driver() + + return value def get_config(self): with self.lock_config: