From c76f633c0f4057566cc6b75506052db1be78e1ef Mon Sep 17 00:00:00 2001 From: Joe Ziminski <55797454+JoeZiminski@users.noreply.github.com> Date: Fri, 27 Sep 2024 09:50:57 +0100 Subject: [PATCH] Fix error from new textualize from dismiss in call_after_refresh. (#412) * Fix error from new textualize from dismiss in call_after_refresh. * Fix test error due to change in textual error message :( * fullstop addition Co-authored-by: Niko Sirmpilatze --------- Co-authored-by: Niko Sirmpilatze --- datashuttle/tui/screens/modal_dialogs.py | 13 +++++----- datashuttle/tui/tabs/transfer.py | 33 +++++++++++++++++++++--- tests/tests_tui/test_tui_settings.py | 2 +- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/datashuttle/tui/screens/modal_dialogs.py b/datashuttle/tui/screens/modal_dialogs.py index fbc63b35d..057186367 100644 --- a/datashuttle/tui/screens/modal_dialogs.py +++ b/datashuttle/tui/screens/modal_dialogs.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Callable, Optional if TYPE_CHECKING: from pathlib import Path @@ -72,9 +72,10 @@ class FinishTransferScreen(ModalScreen): taking user input ('OK' or 'Cancel'). """ - def __init__(self, message: str) -> None: + def __init__(self, message: str, transfer_func: Callable) -> None: super().__init__() + self.transfer_func = transfer_func self.message = message def compose(self) -> ComposeResult: @@ -90,15 +91,15 @@ def compose(self) -> ComposeResult: def on_button_pressed(self, event: Button.Pressed) -> None: if event.button.id == "confirm_ok_button": - # Update the display to 'transferring' before TUI freezes - # during data transfer. + # Update the display to 'transferring' before + # TUI freezes during data transfer. self.query_one("#confirm_button_container").visible = False self.query_one("#confirm_message_label").update("Transferring...") self.query_one("#confirm_message_label").call_after_refresh( - lambda: self.dismiss(True) + lambda: self.transfer_func(True) ) else: - self.dismiss(False) + self.transfer_func(False) class SelectDirectoryTreeScreen(ModalScreen): diff --git a/datashuttle/tui/tabs/transfer.py b/datashuttle/tui/tabs/transfer.py index a7e469a1c..59fd6597b 100644 --- a/datashuttle/tui/tabs/transfer.py +++ b/datashuttle/tui/tabs/transfer.py @@ -85,6 +85,7 @@ def __init__( self.show_legend = self.mainwindow.load_global_settings()[ "show_transfer_tree_status" ] + self.finish_transfer_screen: Optional[FinishTransferScreen] = None # Setup # ---------------------------------------------------------------------------------- @@ -277,8 +278,22 @@ def on_button_pressed(self, event: Button.Pressed) -> None: to confirm that the user wishes to transfer their data (in the direction selected). If "Yes" is selected, `self.transfer_data` (see below) is run. - """ + Notes + ----- + The way that Textualize works makes it difficult (impossible?) + to render a screen but keep the main loop with another screen. + What we want to do is 1) select 'OK' to start transfer + 2) show 'Transferring...' 3) transfer data 4) tear down 'transferring' + screen 5) show confirmation screen. This is not simple if we want to + manage the actual transfer in this screen, which makes a lot of + sense as all options are held here. The alternative is to pass all settings + to a `Transferring` modal dialog which seems even more convoluted. So, + `FinishTransferScreen` calls back to `self.transfer_data`. If 'OK' was + selected, the message is changed to 'Transferring'. Then, `self.transfer_data` + handles data transfer, teardown of the `FinishTransferScreen` + and display of the confirmation screen. + """ if event.button.id == "transfer_transfer_button": if not self.query_one("#transfer_switch").value: direction = "upload" @@ -294,9 +309,15 @@ def on_button_pressed(self, event: Button.Pressed) -> None: " central filesystem.\n\nAre you sure you wish to proceed?\n", ) - self.mainwindow.push_screen( - FinishTransferScreen(message), self.transfer_data + # This is very convoluted. See docstring for details. + assert ( + self.finish_transfer_screen is None + ), "`finish_transfer_screen` should de cleaned up in `transfer_data`." + + self.finish_transfer_screen = FinishTransferScreen( + message, self.transfer_data ) + self.mainwindow.push_screen(self.finish_transfer_screen) def on_custom_directory_tree_directory_tree_special_key_press( self, event: CustomDirectoryTree.DirectoryTreeSpecialKeyPress @@ -337,6 +358,12 @@ def transfer_data(self, transfer_bool: bool) -> None: transfer by clicking "Yes". """ + # Teardown the screen first, whatever `transfer_bool` is. + # It will not be updated until the transfer is complete. + assert self.finish_transfer_screen is not None + self.finish_transfer_screen.dismiss() + self.finish_transfer_screen = None + if transfer_bool: upload = not self.query_one("#transfer_switch").value diff --git a/tests/tests_tui/test_tui_settings.py b/tests/tests_tui/test_tui_settings.py index 2126de76f..0acbd0908 100644 --- a/tests/tests_tui/test_tui_settings.py +++ b/tests/tests_tui/test_tui_settings.py @@ -77,7 +77,7 @@ async def test_show_transfer_tree_status(self, setup_project_paths): with pytest.raises(BaseException) as e: transfer_tab.query_one("#transfer_legend") - assert "No nodes match