diff --git a/assets/gui/css/alas.css b/assets/gui/css/alas.css index 7d085f1..a31fefb 100644 --- a/assets/gui/css/alas.css +++ b/assets/gui/css/alas.css @@ -315,6 +315,16 @@ pre.rich-traceback-code { margin: 0; } +.anim-rotate { + animation: rotate-keyframes 0.4s linear infinite +} + +@keyframes rotate-keyframes { + 100% { + transform: rotate(360deg) + } +} + #pywebio-scope-contents { margin-top: 0; overflow-y: auto; diff --git a/module/webui/app.py b/module/webui/app.py index e32f040..957788c 100644 --- a/module/webui/app.py +++ b/module/webui/app.py @@ -108,6 +108,11 @@ class AlasGUI(Frame): self.alas_config = AzurLaneConfig("template") self.alas_config_hidden = set() self.initial() + # rendered state cache + self.rendered_cache = [] + self.inst_cache = [] + self.load_home = False + self.af_flag = False @use_scope("aside", clear=True) def set_aside(self) -> None: @@ -119,12 +124,11 @@ class AlasGUI(Frame): ], onclick=[self.ui_develop], ), - for name in alas_instance(): - put_icon_buttons( - Icon.RUN, - buttons=[{"label": name, "value": name, "color": "aside"}], - onclick=self.ui_alas, - ) + put_scope("aside_instance", [ + put_scope(f"alas-instance-{i}", []) + for i, _ in enumerate(alas_instance()) + ]) + self.set_aside_status() put_icon_buttons( Icon.ADD, buttons=[ @@ -133,6 +137,52 @@ class AlasGUI(Frame): onclick=[self.ui_add_alas], ), + current_date = datetime.now().date() + if current_date.month == 4 and current_date.day == 1: + self.af_flag = True + + @use_scope("aside_instance") + def set_aside_status(self) -> None: + flag = True + + def update(name, seq): + with use_scope(f"alas-instance-{seq}", clear=True): + icon_html = Icon.RUN + rendered_state = ProcessManager.get_manager(inst).state + if rendered_state == 1 and self.af_flag: + icon_html = icon_html[:31] + ' anim-rotate' + icon_html[31:] + put_icon_buttons( + icon_html, + buttons=[{"label": name, "value": name, "color": "aside"}], + onclick=self.ui_alas, + ) + return rendered_state + + if not len(self.rendered_cache) or self.load_home: + # Reload when add/delete new instance | first start app.py | go to HomePage (HomePage load call force reload) + flag = False + self.inst_cache.clear() + self.inst_cache = alas_instance() + if flag: + for index, inst in enumerate(self.inst_cache): + # Check for state change + state = ProcessManager.get_manager(inst).state + if state != self.rendered_cache[index]: + self.rendered_cache[index] = update(inst, index) + flag = False + else: + self.rendered_cache.clear() + clear("aside_instance") + for index, inst in enumerate(self.inst_cache): + self.rendered_cache.append(update(inst, index)) + self.load_home = False + if not flag: + # Redraw lost focus, now focus on aside button + aside_name = get_localstorage("aside") + self.active_button("aside", aside_name) + + return + @use_scope("header_status") def set_status(self, state: int) -> None: """ @@ -1082,6 +1132,7 @@ class AlasGUI(Frame): def show(self) -> None: self._show() + self.load_home = True self.set_aside() self.init_aside(name="Home") self.dev_set_menu() @@ -1227,6 +1278,7 @@ class AlasGUI(Frame): ) self.task_handler.add(self.state_switch.g(), 2) + self.task_handler.add(self.set_aside_status, 2) self.task_handler.add(visibility_state_switch.g(), 15) self.task_handler.add(update_switch.g(), 1) self.task_handler.start()